home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
wdj0697.zip
/
SDKANN.ZIP
/
SDKANN.TXT
< prev
next >
Wrap
Text File
|
1997-05-07
|
140KB
|
4,375 lines
Please send us your annotations! Just email them to
70302.2566@compuserve.com and indicate the topic and
the help file that your annotation refers to. Help
us build the SDK annotation database!
1/9/97 NOTE:
This version fixes a bug that caused some untoward
crashes. This version also revises the logic for
mstater.exe, and may actually work with Visual C++ 4.2,
though I have not tried it yet.
11/21/96 NOTE:
The win32.hlp file that ships with Borland C++ v5.01 seems
to be missing the help topics that correspond to annotations
#126 (AVIFileOpen) and #140 (the STGM structure).
8/29/96 NOTE:
Readers have reported that mstater.exe does not work
with Visual C++ v4.2. Unfortunately, I don't yet have
that version of the compiler. As soon as I get it, I will
try to modify mstater.exe to work correctly with it.
5/8/96 NOTE:
The AnnTater utility mentioned below has been mutated
to work with the InfoViewer that is integrated in
the Visual C++ IDE. Instead of running anntater.exe,
run mstater.exe if you want to annotate the IDE
InfoViewer (rather than any .hlp files you may have).
Let me know if you have problems.
12/1/95 NOTE:
The WDJ annotation package now includes anntater.exe.
AnnTater contains all of our annotations and you can use it
to automatically place our annotations in your help file.
Although I've tried to test this software in a variety of
situations, USE IT AT YOUR OWN RISK. If you have
annotations of your own, you may want to back up your .ann
file before running AnnTater. To use AnnTater, follow
these steps. If you don't have annotations of your own, the
easiest route is to delete your .ann file each time you run
anntater.exe on a new installment of our annotations.
1) invoke anntater.exe
2) select a type of help file (Windows 3.1 API or Win32 API)
3) if necessary, press the Locate button to specify the
path where this helpfile exists
4) select one or more annotations that you want to install
5) press the Copy button
6) press Done
Note that the program displays a checkmark beside
each annotation that it believes it has successfully
installed during the current session.
----------
This is the Windows Developer's Journal SDK Annotation File, a
growing collection of useful annotations for the standard online Windows
API help file, win31wh.hlp, which is included with every Windows C++
compiler. You can either cut and paste these annotations into your own
SDK help file (use ALT-E-A to create a help topic annotation), or you
can use anntater.exe to install them automatically for you.
If you have a useful annotation you would like to submit to our
collection, send it to:
70302.2566@compuserve.com
If we use your annotation, you will be listed as the
contributor. Our thanks to the dozens of readers whose
contributions help us continue to build this database of
useful information for the Windows programming community.
Windows Developer's Journal
"The Magazine for Windows Developers"
Windows Developer's Journal is the monthly publication for
advanced Windows programmers. We cover a variety of topics
such as Windows 95 programming, NT programming device
drivers, undocumented functions, compiler bugs, operating
system bugs, graphics, MFC, multimedia, communications, and
so on -- usually in the form of reusable code that you can
use immediately (most of our code has been compiled with
both Borland and Microsoft C/C++ compilers). In addition,
each month contains regular features like these:
* SDK Annotations
(they appear in the magazine before they appear in this file)
* Bug++ of the Month
(nasty bugs in popular C++ compilers)
* Tech Tips
(user-submitted tips and techniques)
* Books in Brief
(quick looks at recent books)
* Understanding NT
(covers NT-specific programming issues)
and more. WDJ costs $34.99/year in the US, $45/year Canada/Mexico, or
$64/year overseas. To order a subscription, contact
Miller Freeman
P.O. Box 56565
Boulder, CO 80322-6565
(800) 365-1425
(303) 678-0439
wdsub@rdpub.com
To subscribe by email or fax, include your name, address,
phone number, MasterCard or Visa number, and expiration
date. From CompuServe, that email address would be
something like this:
>INTERNET:wdsub@rdpub.com
Note: Annotation #35 proved to be incorrect and was
removed.
Note: due to a bug in WinHelp, it is not possible to display
or annotate the GetRgnBox topic in the Visual C++ v1.5
version of the helpfile. This prevents #67 from being
properly installed.
------------------------------------------------------------
WDJ SDK Annotation #1
TYPE: Win3.1
TOPIC: Dialog Boxes
KEYWORD: Dialog Boxes
If a listbox is the first control in a dialog's tab order
and the dialog box was not created with the WS_VISIBLE
style, the listbox does not correctly draw itself with the
focus.
Reference: p35, March 1993 Windows/DOS Developer's Journal.
------------------------------------------------------------
WDJ SDK Annotation #2
TYPE: Win3.1
TOPIC: Property Lists
KEYWORD: Property Lists
The oft-quoted maxim that using window properties is slower
than using class or window extra bytes (via
GetWindowWord()/SetWindowWord()) is totally false if you use
a global atom rather than a string to name the property.
Properties were about 20% slower than window words under
Windows 3.0, but under Windows 3.1 GetProp() is about 300%
faster than GetWindowWord().
Reference: p 49, March 1993 Windows/DOS Developer's Journal.
------------------------------------------------------------
WDJ SDK Annotation #3
TYPE: Win3.1
TOPIC: WM_MOUSEMOVE (2.x)
KEYWORD: WM_MOUSEMOVE
The documentation incorrectly states that the x and y
arguments are in screen coordinates. They are in client
coordinates.
------------------------------------------------------------
WDJ SDK Annotation #4 (revised)
TYPE: Win3.1
TOPIC: SetWindowsHookEx (3.1)
KEYWORD: SetWindowsHookEx
SetWindowsHookEx() has a bug: using it to install a
task-specific hook can cause various failures. The
workaround is to pass it a module handle rather than an
instance handle. You can obtain a module handle from
GetModuleHandle(). If you only have the current instance
handle and not the name of the module, use the following
undocumented hack under Windows 3.1:
GetModuleHandle(MAKELP(0,hInstance));
If you #include <windowsx.h>, you can instead use the macro
GetInstanceModule(hInstance). Under Windows NT, just pass a
NULL to obtain the handle of the current process. Note that
the MSDN News article on this subject has the arguments to
MAKELP() backwards.
Reference: MSDN News #1, 1993
Revised by: Tom Nolan
------------------------------------------------------------
WDJ SDK Annotation #5
TYPE: Win3.1
TOPIC: CS_BYTEALIGNWINDOW 0x2000
KEYWORD: CS_BYTEALIGNWINDOW
The documentation makes it sound like this style bit is the
one you want for efficient bitblts. In fact, most of your
bitblts will be to the client area of the window, not the
non-client area, so CS_BYTEALIGNCLIENT is the style bit you
should set if you are concerned about bitblt operation
efficiency. Unaligned windows are slower at VGA resolution,
but typically not an issue with higher resolution
adapters (such as 256-color SVGA).
Reference: p65, December 1993 Windows/DOS Developer's Journal.
------------------------------------------------------------
WDJ SDK Annotation #6
TYPE: Win3.1
TOPIC: CODE Module Definition Statement
KEYWORD: CODE Module Definition Statement
The documentation for the FIXED attribute is incorrect.
Under Windows 3.1, if you mark code or data segments in your
.exe FIXED, the loader ignores that attribute -- the
segments will be moveable. If you mark code or data
segments in your .dll FIXED, however, the loader will make
them fixed and will page lock them as well. Due to the
implementation of GlobalPageLock(), that can result in your
segments using up precious DOS memory, eventually preventing
Windows from spawning new applications (since each new
application needs at least 512 bytes of DOS memory for a
task database entry). The October 1994 Windows
Developer's Journal provides code to allocate fixed memory
without using up precious conventional memory.
------------------------------------------------------------
WDJ SDK Annotation #7
TYPE: Win3.1
TOPIC: WS_EX_TRANSPARENT 0x00000020L
KEYWORD: WS_EX_TRANSPARENT
Note that this bit does not really create transparent
windows. If you create a window with this style, it is true
that the windows below it will show through as its
background. However, if you then move your new window, it
will have the same background as it did in its original
position -- blotting out whatever it is covering in its new
position.
------------------------------------------------------------
WDJ SDK Annotation #8
TYPE: Win3.1
TOPIC: WM_NCHITTEST (2.x)
KEYWORD: WM_NCHITTEST
You can process this message to allow the user to drag a
window that does not have a title bar. When you receive a
WM_NCHITTEST message and the mouse is in your client area
(or whatever conditions you want to start the drag), just
return HTCAPTION rather than passing the message on to
DefWindowProc().
Reference: p 37, March 1993 Windows/DOS Developer's Journal.
------------------------------------------------------------
WDJ SDK Annotation #9
TYPE: Win3.1
TOPIC: WM_TIMER (2.x)
KEYWORD: WM_TIMER
Although it sounds odd, you can use a WM_TIMER message as a
way to kill another application, if you can obtain the
handle of the main of the application you want to kill.
Create a timer callback function that does nothing but pass
its first argument (window handle) to DestroyWindow(). Then
use PostMessage() to post (to the other app's main window) a
WM_TIMER message that points to your callback function.
Your timer callback will get executed in the context of the
target application.
Reference: p 64, September 1992 Windows/DOS Developer's Journal.
------------------------------------------------------------
WDJ SDK Annotation #10
TYPE: Win3.1
TOPIC: MemoryWrite (3.1)
KEYWORD: MemoryWrite
MemoryWrite() has a bug in it: it trashes the high 16 bits
of the EDI register (the 32-bit version of the DI register).
The workaround is to save the register before calling
MemoryWrite() and restore it afterward.
Reference: p. 71, April 1994 Windows/DOS Developer's Journal
------------------------------------------------------------
WDJ SDK Annotation #11
TYPE: Win3.1
TOPIC: EscapeCommFunction (2.x)
KEYWORD: EscapeCommFunction
The documentation omits one potential value for the
nFunction parameter, although it is defined in windows.h.
The name is GETBASEIRQ and it returns the base address of
the COM port in the lower word and the IRQ setting in the
high word. If the high word is -1 the port doesn't exist;
if it is 0, the comm driver does not support this escape
(which is the case, for example with some kinds of enhanced
serial boards).
Submitted by: Thomas Zeisluft
------------------------------------------------------------
WDJ SDK Annotation #12
TYPE: Win3.1
TOPIC: MessageBox (2.x)
KEYWORD: MessageBox
Do not call MessageBox() from within the LibMain() of an
implicitly-linked DLL. It will fail because the application
will not yet have a message queue at that point, and
MessageBox() (or anything else) cannot create its window
when the message queue does not yet exist. Once the
application executes its internal startup code and calls
InitApp(), then it has a message queue and can safely call
functions that create windows.
------------------------------------------------------------
WDJ SDK Annotation #13
TYPE: Win3.1
TOPIC: LB_ADDSTRING (2.x)
KEYWORD: LB_ADDSTRING
If you are changing the contents of a listbox (for example,
by adding or deleting multiple strings), you may want to
minimize screen redrawing and maximize speed by disabling
window redrawing during your operation. Follow these steps:
1) Send a WM_SETREDRAW with wParam equal to FALSE to the listbox.
2) Perform your adds or deletes.
3) Send a WM_SETREDRAW with wParam equal to TRUE to the listbox.
4) Use InvalidateRect() to force the listbox to redraw itself.
Revised by V. Ramachandran
------------------------------------------------------------
WDJ SDK Annotation #14
TYPE: Win3.1
TOPIC: RegisterWindowMessage (2.x)
KEYWORD: RegisterWindowMessage
Do you really need to register a private window message?
Probably not, if all you need is an intra-app message number
that does not conflict with any Windows message numbers.
Microsoft has revised its statement about what message
numbers are available for your private use. Microsoft now
guarantees that you can use message numbers 0x8000 through
0xBFFF and they will not conflict with any system messages.
They also claim the next SDK (Chicago?) will define WM_APP
equal to 0x8000 in windows.h.
Reference: Microsoft Knowledge Base article Q86835
------------------------------------------------------------
WDJ SDK Annotation #15
TYPE: Win3.1
TOPIC: WM_CHAR (2.x)
KEYWORD: WM_CHAR
The documentation incorrectly claims that wParam is the
virtual key code. In fact, it is the ASCII value of the key
pressed. For example, pressing the '$' (ASCII 0x5B) key
produces a wParam equal to 0x5B -- if you interpreted that
as a virtual key code, you would incorrectly believe that
the user had pressed VK_HOME!
Submitted by: Brent Rector
------------------------------------------------------------
WDJ SDK Annotation #16
TYPE: Win3.1
TOPIC: WinHelp (3.0)
KEYWORD: WinHelp
The documentation says that the return value is nonzero if
WinHelp() is successful. In fact, WinHelp() only returns
failure for systemic problems, like being unable to allocate
global memory, or being unable to spawn winhelp.exe. If
WinHelp() successfully passes your request to winhelp.exe,
it returns success, period. So, for example, if the named
help file is invalid, or you try to jump to a help topic
that does not exist, or any number of other logical errors,
WinHelp() still returns success.
------------------------------------------------------------
WDJ SDK Annotation #17
TYPE: Win3.1
TOPIC: WM_ENTERIDLE (2.x)
KEYWORD: WM_ENTERIDLE
The documentation says that this messsage gets sent to your
application's "main window". In fact, a dialog sends the
WM_ENTERIDLE message to its own parent window, which may or
may not happen to be your application's main window.
------------------------------------------------------------
WDJ SDK Annotation #18
TYPE: Win3.1
TOPIC: OPENFILENAME (3.1)
KEYWORD: OPENFILENAME
The documentation does not completely describe the behavior
when selecting multiple files. To allow the user to select
multiple files, you turn on the flag OFN_ALLOWMULTISELECT.
If you do that and call GetOpenFileName(), and if the user then
selects multiple files, then GetOpenFileName() will copy (into
lpstrFile) the path, followed by a space, followed by
space-separated filenames. For example, if the user
selected files "fred.1" and "fred.2" from directory
"c:\test", lpstrFile would then point to the following
string:
"c:\test fred.1 fred.2"
However, the documentation does not point out that if the
user selects only one file, then the path is not kept
separate from the filename. Using the previous example, if
the user selected only file "fred.1", then lpstrFile would
point to this:
"c:\test\fred.1"
Submitted by Julian Templeman
------------------------------------------------------------
WDJ SDK Annotation #19
TYPE: Win3.1
TOPIC: CreateRoundRectRgn (3.0)
KEYWORD: CreateRoundRectRgn
This function has a bug. It will produce a GP fault if the
region rectangle is empty (either nLeftRect equals
nRightRect, or nBottomRect equals nTopRect). About the only
workaround is to create a wrapper function that first checks
whether the rectangle is empty.
Reference: p67, June 1994 Windows/DOS Developer's Journal^
Submitted by Chris Mason
------------------------------------------------------------
WDJ SDK Annotation #20
TYPE: Win3.1
TOPIC: EnableMenuItem (2.x)
KEYWORD: EnableMenuItem
When you are making changes to a window menu, the menu bar
is not immediately updated. To force those changes (such as
enabling/disabling menu items) to be visible right away,
make sure you call DrawMenuBar().
------------------------------------------------------------
WDJ SDK Annotation #21
TYPE: Win3.1
TOPIC: DrawText (2.x)
KEYWORD: DrawText
DrawText() has an off-by-one error that can result in a GP
fault. The bug is evoked when you use pass an explicit
string length instead of NULL-terminating the text string.
The bug is not evoked if you use the DT_NOPREFIX flag, or if
you NULL-terminate the text string (the easiest workaround).
Reference: p53, August 1994 Windows/DOS Developer's Journal
------------------------------------------------------------
WDJ SDK Annotation #22
TYPE: Win3.1
TOPIC: WM_MEASUREITEM (3.0)
KEYWORD: WM_MEASUREITEM
Windows supports owner-draw menus, but only popup owner-draw
menus work correctly. If you try to create an owner-draw
menubar for a window, Windows will not send you the
WM_MEASUREITEM message as it should.
Reference: Microsoft Knowledge Base article Q69969
------------------------------------------------------------
WDJ SDK Annotation #23
TYPE: Win3.1
TOPIC: WINDOWPOS (3.1)
KEYWORD: WINDOWPOS
The documentation says that y is "the position of the right
edge of the window". It is, of course, the position of the
top edge of the window.
------------------------------------------------------------
WDJ SDK Annotation #24
TYPE: Win3.1
TOPIC: Shell Dynamic-Data Exchange Interface Overview (3.1)
KEYWORD: Shell Dynamic-Data Exchange Interface Overview
The documentation says you can use DDE to get a list of
Program Manager groups by "issuing a request for the Group
item." In fact, that is not the correct item name -- you
must use 'Groups', not 'Group'.
------------------------------------------------------------
WDJ SDK Annotation #25
TYPE: Win3.1
TOPIC: TrackPopupMenu (3.0)
KEYWORD: TrackPopupMenu
The documentation incorrectly states that you can pass the
TPM_RIGHTBUTTON flag if you want the menu to respond to the
right (secondary) mouse button instead of the left (primary)
mouse button. In fact, passing TPM_RIGHTBUTTON causes the
menu to respond to the right mouse button as well as the
left. There is apparently no combination of bits that cause
the menu to respond only to the right mouse button.
------------------------------------------------------------
WDJ SDK Annotation #26
TYPE: Win3.1
TOPIC: SetDlgItemText (2.x)
KEYWORD: SetDlgItemText
There is a bug in Windows that keeps SetWindowText() and
SetDlgItemText() from working correctly when applied to an
edit control owned by another application. Rather than
sending a WM_SETTEXT to the edit control as they should,
these functions directly tinker with the target control's
internal window structure to change its title. The bug,
then, is twofold:
a) The target window is never notified that it
needs to repaint.
b) An edit control ignores its title, so changing
its title does not affect the text it contains.
The workaround is to use SendMessage() or PostMessage() to
deliver a WM_SETTEXT to the target window. If you use
PostMessage(), make sure you pass a string pointer that is
somehow guaranteed to still be valid whenever the target
application gets around to fetching and processing the
message.
Reference: p. 71, September 1993 Windows/DOS Developer's Journal
------------------------------------------------------------
WDJ SDK Annotation #27
TYPE: Win3.1
TOPIC: GetMenuItemID (2.x)
KEYWORD: GetMenuItemID
The documentation says that this function returns 0 if the
specified menu item is a separator. In fact, although the
resource compiler implicitly assigns separators an ID of 0,
you can assign them any 16-bit ID you like (with
ModifyMenu(), InsertMenu(), etc.) and this function will
return the correct ID, not just zero.
------------------------------------------------------------
WDJ SDK Annotation #28
TYPE: Win3.1
TOPIC: GetMetaFile (2.x)
KEYWORD: GetMetaFile
Most programs that write a "Windows metafile" to disk use a
newer file format that this function does not understand.
Most programs read and write "placeable" metafiles, a
metafile with a 22-byte header that contains a minimum
bounding rectangle for the figure. If you want to read in a
metafile that may have been written by another application,
you should open the file yourself and check the header to
see if it is a placeable metafile. See the SDK
documentation for a description of "placeable Windows
metafiles".
Reference: p. 43, November 1994 Windows/DOS Developer's Journal
------------------------------------------------------------
WDJ SDK Annotation #29
TYPE: Win3.1
TOPIC: WritePrivateProfileString (3.0)
KEYWORD: WritePrivateProfileString
The documentation for WritePrivateProfileString() and the
prototypes in windows.h, indicate that all strings passed in
are LPCSTR (32-bit pointer to unmodifiable character
string). However, sometimes this function writes on your
input string anyway! For one example, if you pass in the
string
"Hello World "
the function will remove the trailing spaces by writing a
NULL byte after the 'd'. If you were passing in a constant
string that resided in a code segment, this aberrant
behavior could result in a GP fault. This function
absolutely should not modify a string declared as LPCSTR,
but since it does, beware!
Submitted by Charles Leamon
------------------------------------------------------------
WDJ SDK Annotation #30
TYPE: Win3.1
TOPIC: GetMenuState (2.x)
KEYWORD: GetMenuState
In addition to the bits noted in the documentation, this
function also correctly returns MF_POPUP for a submenu.
Oddly, if you located the popup by position, the
MF_BYPOSITION flag will also be set in the returned flags,
although it is not on when used to locate normal menu items.
Note that some of these flags equate to zero, so you cannot
just AND them with the returned flags to see if they are on.
Here are the flags that equate to zero, along with the
expression you can use to infer their presence:
Zero Flag Expression to test for flag
============== =================================
MF_ENABLED !(Flag&~(MF_DISABLED|MF_GRAYED))
MF_UNCHECKED !(Flag&~MF_CHECKED)
MF_STRING !(Flag&~(MF_BITMAP|MF_OWNERDRAW))
------------------------------------------------------------
WDJ SDK Annotation #31
TYPE: Win3.1
TOPIC: GetWindowPlacement (3.1)
KEYWORD: GetWindowPlacement
From the documentation, you might think the following code
would work:
WINDOWPLACEMENT Info;
GetWindowPlacement(hWnd, &Info);
In fact, it won't. You must remember to initialize the
"length" field of the structure before calling this
function. The following code works:
WINDOWPLACEMENT Info;
Info.length = sizeof(Info);
GetWindowPlacement(hWnd, &Info);
Submitted by Pete Davis
------------------------------------------------------------
WDJ SDK Annotation #32
TYPE: Win3.1
TOPIC: CreateCompatibleBitmap (2.x)
KEYWORD: CreateCompatibleBitmap
The description of height and width parameters states that
these values are in bits, when actually they are in pixels.
Submitted by Charles Leamon
------------------------------------------------------------
WDJ SDK Annotation #33
TYPE: Win3.1
TOPIC: LoadCursor (2.x)
KEYWORD: LoadCursor
The documentation says that you should call DestroyCursor()
for cursors loaded via LoadCursor(). That is wrong -- you
should only call DestroyCursor() for cursors created with
CreateCursor().
Submitted by Charles Leamon^
Reference: Microsoft Knowledge Base article Q84779
------------------------------------------------------------
WDJ SDK Annotation #34
TYPE: Win3.1
TOPIC: lstrcpyn (3.1)
KEYWORD: lstrcpyn
The documentation for lstrcpyn() states that the last
parameter (cChars) is the number of characters to be copied,
when in fact the number of characters will be cChars-1.
That's convenient, but it's not what it says and it's
inconsistent with the standard ANSI C run-time function
strncpy(), which does copy the specified count. In other
words, unlike strncpy(), this function always
NULL-terminates the destination string.
Submitted by Charles Leamon
------------------------------------------------------------
WDJ SDK Annotation #36
TYPE: Win3.1
TOPIC: ExitWindows (3.0)
KEYWORD: ExitWindows
The documentation is incomplete. To just terminate Windows
and return control to DOS, pass a zero in the dwReturnCode
parameter.
Submitted by Charles Leamon^
Reference: Microsoft Knowledge Base article Q100359
------------------------------------------------------------
WDJ SDK Annotation #37
TYPE: Win3.1
TOPIC: OpenFile (2.x)
KEYWORD: OpenFile
The descriptions for OF_CANCEL and OF_PROMPT are incorrect.
OF_CANCEL does not add a cancel button to the 'File not
found' (OF_PROMPT) dialog. Even if it did, how would the
caller know the user pressed the cancel button (only one
error return is defined for OpenFile())? The OF_PROMPT
dialog does not prompt the user to insert a diskette into
drive A:
Submitted by Charles Leamon
------------------------------------------------------------
WDJ SDK Annotation #38
TYPE: Win3.1
TOPIC: WM_NCHITTEST (2.x)
KEYWORD: WM_NCHITTEST
The documentation claims that this message is sent to the
window that used SetCapture() to capture mouse input. That
is totally false. The window whose handle is passed to
SetCapture() will never receive any WM_NCHITTEST messages
(no matter where you move the moust) while the mouse is
captured.
Submitted by V. Ramachandran
------------------------------------------------------------
WDJ SDK Annotation #39
TYPE: Win3.1
TOPIC: TabbedTextOut (3.0)
KEYWORD: TabbedTextOut
The documentation claims that the tab stops are in device
units (pixels), but that is not true. The tab stops are
treated as logical units, not device units.
Submitted by Dan Miser^
Reference: Microsoft Knowledge Base article Q113253
------------------------------------------------------------
WDJ SDK Annotation #40
TYPE: Win3.1
TOPIC: LoadIcon (2.x)
KEYWORD: LoadIcon
The documentation says that you should call DestroyIcon()
for cursors loaded via LoadIcon(). That is wrong -- you
should only call DestroyIcon() for icons created with
CreateIcon().
Submitted by Charles Leamon^
Reference: Microsoft Knowledge Base article Q84779
------------------------------------------------------------
WDJ SDK Annotation #41
TYPE: Win3.1
TOPIC: COMPAREITEMSTRUCT (3.0)
KEYWORD: COMPAREITEMSTRUCT
Note that Windows has to send a WM_COMPAREITEM message when
a new item is added to the list, in order to determine its
correct position. That means it does not know the position
of the new item yet, so (contrary to the documentation) the
itemID2 field in this structure will be -1 -- do not assume
it will be a legal index value.
Submitted by V. Ramachandran
------------------------------------------------------------
WDJ SDK Annotation #42
TYPE: Win3.1
TOPIC: GetProcAddress (2.x)
KEYWORD: GetProcAddress
In attempting to locate the named function in the target
module, GetProcAddress() converts the function name to
uppercase and then performs a case-sensitive search. That
means that GetProcAddress() cannot locate functions exported
with names containing lowercase characters. Normally,
that's not a problem, as the __pascal calling sequence
forces uppercase names. However, depending on the compiler
and linker tools and options you use, it is possible to
export __cdecl calling sequence functions with lowercase
characters, resulting in a function that GetProcAddress()
cannot locate.
Submitted by Keith Bluestone
------------------------------------------------------------
WDJ SDK Annotation #43
TYPE: Win3.1
TOPIC: SetScrollRange (2.x)
KEYWORD: SetScrollRange
The documentation says you can use this function to hide or
show standard scroll bars, but does not tell you how!
Basically, if you specify the same value for both the
minimum (nMin) and maximum (nMax) scrolling positions, the
function will hide the scroll bar. If the two positions are
not equal, the function will display the scroll bar.
Submitted by Paul Bonneau
------------------------------------------------------------
WDJ SDK Annotation #44
TYPE: Win3.1
TOPIC: LoadLibrary (2.x)
KEYWORD: LoadLibrary
If LoadLibrary() cannot find the library, it may display an
error message to the user, depending upon the state of
Windows' "error mode". If you want to handle that case
yourself and make sure Windows does not display the error
message, see the documentation for the function
SetErrorMode(). For example, the following code attempts to
load the library ctl3d.dll, but does not emit an error
message if it is not found.
HINSTANCE Ctl3d;^
UINT OldFlag = SetErrorMode(SEM_NOOPENFILEERRORBOX);^
Ctl3d = LoadLibrary("ctl3d.dll");^
SetErrorMode(OldFlag); // restore previous mode^
if(Ctl3d <= HINSTANCE_ERROR)^
// LoadLibrary() failed for some reason^
------------------------------------------------------------
WDJ SDK Annotation #45
TYPE: Win3.1
TOPIC: LoadLibrary (2.x)
KEYWORD: LoadLibrary
The documentation claims this function returns an error code
of 0 if "System was out of memory, executable file was
corrupt, or relocations were invalid". However, if a
library's LibMain() function returns 0 (signifying some
logical error during initialization), LoadLibrary() also
returns 0. Therefore, do not assume that a 0 error code
means the system was out of memory or that the module was
corrupt in some way.
------------------------------------------------------------
WDJ SDK Annotation #46
TYPE: Win3.1
TOPIC: DdeClientTransaction (3.1)
KEYWORD: DdeClientTransaction
The documentation does not say so, but the cbData argument
(length of data) must include the NULL byte if the data is a
string. In other words, if lpvData is a string, cbData must
be set to strlen(lpvData)+1. Otherwise, bad things may
happen in DDEML when you perform an XTYP_POKE or
XTYP_EXECUTE.
Submitted by Mark Reha^
Reference: Microsoft Knowledge Base article Q107387.
------------------------------------------------------------
WDJ SDK Annotation #47
TYPE: Win3.1
TOPIC: WinHelp (3.0)
KEYWORD: WinHelp
The WinHelp() API function normally allows one to execute
macros, jumps, popups, and so on. However, if WinHelp was
started with WinExec() (i.e. from Program Manager or File
Manager) instead of the WinHelp() API function, you will not
be able to execute macros or jumps on that help file without
starting up a second instance of the help file using the
WinHelp() API function.
There is one way around this. You can create a DLL with an
LDLLHandler that gets the callback address for the FAPI()
function from WinHelp. FAPI() has the same parameters as
the WinHelp() API function except that the first parameters
(HWND) is not in FAPI() (so FAPI() only has 3 parameters).
The FAPI() function will allow you to execute macros, jumps,
popups, etc regardless of how WinHelp was launched. For
more information, get the Windows Help Authors Guide from
the MSDN CD-ROM or see Jim Mischel's book "The Developer's
Guide to WINHELP.EXE".
Submitted by Pete Davis
------------------------------------------------------------
WDJ SDK Annotation #48
TYPE: Win3.1
TOPIC: _fpmath (2.x)
KEYWORD: _fpmath
When setting the handler for coprocessor error exceptions
(function 3), the documentation incorrectly says you should
place the address of your exception handler in DS:AX. The
correct registers to use for this 32-bit address are DX:AX.
Submitted by Manfred Keul
------------------------------------------------------------
WDJ SDK Annotation #49
TYPE: Win3.1
TOPIC: VerQueryValue (3.1)
KEYWORD: VerQueryValue
Amazingly, even though the second parameter to this function
is declared const (LPCSTR), VerQueryValue() modifies that
string anyway! Apparently the code replaces a '\' in your
string with a NULL byte temporarily and then puts it back.
This is a bug. For example, suppose you use a compiler
option that places constant strings in read-only code
segments (for Microsoft, "/Gf"; for Borland "-dc"). In that
case, passing such a constant string as the second argument
to this function results in a GP fault.
Submitted by David Lowndes
------------------------------------------------------------
WDJ SDK Annotation #50
TYPE: Win3.1
TOPIC: GetProfileString (2.x)
KEYWORD: GetProfileString
This applies to both GetProfileString() and
GetPrivateProfileString(). If the default value for these
functions contains trailing blanks and the default value is
used because the key did not appear in the INI file, Windows
will null-terminate the string (even though it is declared
const!) at the first trailing blank. If that string is a
literal string and the code is compiled with some
optimizations then the string will end up in a code segment,
resulting in a GPF when the API function attempts to modify
it.
GetProfileString() and GetPrivateProfileString() also strip
out any leading spaces, and any leading and trailing quotes
(single or double quotes).
Submitted by Michael E. Kropp.^
Revised by Kai Riihioja
------------------------------------------------------------
WDJ SDK Annotation #50
TYPE: Win3.1
TOPIC: GetPrivateProfileString (2.x)
KEYWORD: GetPrivateProfileString
This applies to both GetProfileString() and
GetPrivateProfileString(). If the default value for these
functions contains trailing blanks and the default value is
used because the key did not appear in the INI file, Windows
will null-terminate the string (even though it is declared
const!) at the first trailing blank. If that string is a
literal string and the code is compiled with some
optimizations then the string will end up in a code segment,
resulting in a GPF when the API function attempts to modify
it.
GetProfileString() and GetPrivateProfileString() also strip
out any leading spaces, and any leading and trailing quotes
(single or double quotes).
Submitted by Michael E. Kropp.^
Revised by Kai Riihioja
------------------------------------------------------------
WDJ SDK Annotation #51
TYPE: Win3.1
TOPIC: GetTickCount (2.x)
KEYWORD: GetTickCount
GetTickCount() may return units of milliseconds, but its
resolution is much worse than one millisecond under Windows
3.1. For more accurate timings, call the function
timeGetTime(), which is defined in mmsystem.h.
------------------------------------------------------------
WDJ SDK Annotation #52
TYPE: Win3.1
TOPIC: GetWinFlags (3.0)
KEYWORD: GetWinFlags
GetWinFlags() can also tell you if your 16-bit Windows 3.1
application is running under Windows NT:
if(GetWinFlags() & 0x04000)^
// then we are running under Windows NT^
Submitted by Paula Tomlinson.^
Reference: "The Ultimate Windows Version Detector",
Windows/DOS Developer's Journal, February 1995.
------------------------------------------------------------
WDJ SDK Annotation #53
TYPE: Win3.1
TOPIC: KillTimer (2.x)
KEYWORD: KillTimer
Under at least one condition, KillTimer() does not remove a
pending WM_TIMER message from the message queue as
documented. First, understand that Windows just sets a bit
when a timer fires; it does not generate a WM_TIMER message
at that time. A timer message is secretly added to your
input queue when you call GetMessage() or PeekMessage() and
a timer event is pending and no other messages are in the
queue.
If you are using a PeekMessage() call with the PM_NOREMOVE
flag and if the timer bit is on at that point, PeekMessage()
will place a WM_TIMER message in the queue, but won't remove
it. If you then call KillTimer(), it will ensure the timer
bit is off but won't remove the WM_TIMER message. The next
call to GetMessage() or PeekMessage() returns this WM_TIMER
message. One workaround is to use code like this to
terminate a timer:
KillTimer (hWnd, ID);^
if (LOWORD (GetQueueStatus (QS_TIMER)) & QS_TIMER)^
PeekMessage (&msg, hWnd, WM_TIMER, WM_TIMER, PM_REMOVE);^
Submitted by Mike Mast.
------------------------------------------------------------
WDJ SDK Annotation #54
TYPE: Win3.1
TOPIC: DEVMODE (3.0)
KEYWORD: DEVMODE
The documentation claims that DMCOLOR_COLOR is defined to be
1 and DMCOLOR_MONOCHROME is defined to be 2. In fact, if
you look in print.h you discover that the reverse is true.
Submitted by Bill Liu.
------------------------------------------------------------
WDJ SDK Annotation #55
TYPE: Win3.1
TOPIC: EN_CHANGE (2.x)
KEYWORD: EN_CHANGE
The documentation implies this notification only arises from
actions by the user. In fact, this notification also arises
from programmatic changes, such as from sending a WM_SETTEXT
message to the edit control, or using SetWindowText() (which
sends a WM_SETTEXT message). Not knowing this, you might
code an EN_CHANGE handler that attempts to modify the edit
control text, resulting in another EN_CHANGE notification --
an infinite loop!
Submitted by Scott Smith.
------------------------------------------------------------
WDJ SDK Annotation #56
TYPE: Win3.1
TOPIC: EnumFonts (2.x)
KEYWORD: EnumFonts
The 3.1 documentation for this function specifies that the
third argument is of type FONTENUMPROC. This was true in
previous versions, but in 3.1 this call is deprecated in
favour of the new EnumFontFamilies() API function. The
definition of the FONTENUMPROC type has been updated to take
a NEWTEXTMETRIC parameter, and therefore no longer quite
matches the prototype specified for EnumFonts. Microsoft
provids a new type, OLDFONTENUMPROC, which corresponds to
the STRICT definition of EnumFonts in windows.h, but this is
not reflected in the documentation. In other words, if you
compile with STRICT defined for Windows 3.1 and want to use
EnumFonts(), make sure the third parameter is of type
OLDFONTENUMPROC.
Submitted by David W. Gillett.
------------------------------------------------------------
WDJ SDK Annotation #57
TYPE: Win3.1
TOPIC: PtInRect (2.x)
KEYWORD: PtInRect
There is no mention of this, but the rectangle MUST be
normailized before this function is called. In other words,
you have to make sure that lprc->right is greater than
lprc->left, and that lrpc->bottom is greater than lrpc->top.
Otherwise, the point will never be considered inside of the
rectangle. By contrast, the function RectInRegion() does
accept and correctly handle all rectangles, whether
normalized or not.
Submitted by Peter Ritchie.
------------------------------------------------------------
WDJ SDK Annotation #58
TYPE: Win3.1
TOPIC: SetTimer (2.x)
KEYWORD: SetTimer
The documentation makes it sound like Windows either posts a
message (if you supply no callback function) or else calls
your callback function directly when the timer expires. In
fact, when the timer fires, Windows sets a bit in your
message queue which gets transformed into a WM_TIMER message
by either GetMessage() or PeekMessage() when they find no
other messages in the input queue. The WM_TIMER message
contains the address of your callback function (if any),
which will be called by DefWindowProc() after the message is
dispatched to your window. The key point here is that the
timers created by SetTimer() are always message based
(Windows does not call your timer procedure asynchronously)
and of a lower priority than any other Windows message.
Submitted by Alan M. Carroll.
------------------------------------------------------------
WDJ SDK Annotation #59
TYPE: Win3.1
TOPIC: lstrcpy (2.x)
KEYWORD: lstrcpy
Believe it or not, this function (and apparently other
similar functions) examine the limit of the selector of the
output string, and even attempt to silently recover if the
operation causes a GP fault. As a consequence, you should
not count on this function being a real speed demon.
Submitted by Vivek Venugopalan
------------------------------------------------------------
WDJ SDK Annotation #60
TYPE: Win3.1
TOPIC: GetModuleFileName (2.x)
KEYWORD: GetModuleFileName
Windows 3.1 has a bug that causes this function to sometimes
return relative paths instead of absolute (fully qualified)
paths.This error occurs if a relative path is specified in
the PATH variable, and the DLL is implicitly loaded from
this directory. For example, if the PATH variable is:
PATH=C:\DOS;D:.;C:\UTILS
and an application running from any other directory but
"D:.", loads a DLL (test.dll) in "D:." implicitly (since it
is in the path), then a call to GetModuleFileName() with the
DLL instance will return "D:.\test.dll".
Submitted by V. Ramachandran
Reference: MSKB PSS ID Number: Q85330.
------------------------------------------------------------
WDJ SDK Annotation #61
TYPE: Win3.1
TOPIC: CB_GETDROPPEDCONTROLRECT (3.1)
KEYWORD: CB_GETDROPPEDCONTROLRECT
The documentation claims that this function retrieves the
screen coordinates of the listbox portion of a combo box.
In fact, it retrieves the screen coordinates of the
rectangle that encloses the ENTIRE combo box in its
dropped-down state. That means the rectangle retrieved is
both bit taller and a bit wider than the rectangle that the
help file claims is returned.
Submitted by V. Ramachandran
------------------------------------------------------------
WDJ SDK Annotation #62
TYPE: Win3.1
TOPIC: NotifyUnRegister (3.1)
KEYWORD: NotifyUnRegister
As the documentation says, you can set the htask argument to
NULL to refer to the current task. This is probably not a
good practice, however. If more than one application can
load your DLL, then there is typically some scenario under
which the task that you called NotifyRegister() for has died
before you call NotifyUnRegister(), in which case passing
NULL would refer to the wrong task. It's probably safer to
explicitly store that task that was passed to
NotifyRegister() and make sure you pass the same task to
NotifyUnregister().
Submitted by Paul Dolphin.
------------------------------------------------------------
WDJ SDK Annotation #63
TYPE: Win3.1
TOPIC: CreateCompatibleDC (2.x)
KEYWORD: CreateCompatibleDC
You might think from the name that this function returns a
device context whose attributes are the same as the source
device context. In fact, attributes such as the mapping
mode will be set to their defaults (e.g., the mapping mode
will always be MM_TEXT) in the returned device context, not
to the attribute values of the source device context.
Submitted by Stuart Patterson^
Reference: p. 624, "Programming Windows 3.1, 3rd Edition",
by Charles Petzold
------------------------------------------------------------
WDJ SDK Annotation #64
TYPE: Win3.1
TOPIC: Device Contexts
KEYWORD: Device Contexts
The help file says CreateCompatibleDC() creates a device
context that "has the same attributes" as the source device
context. In fact, the device context's attributes (such as
mapping mode) will have their default values, no matter what
value they had in the source device context.
Submitted by Stuart Patterson^
Reference: p. 624, "Programming Windows 3.1, 3rd Edition",
by Charles Petzold
------------------------------------------------------------
WDJ SDK Annotation #65
TYPE: Win3.1
TOPIC: UngetCommChar (2.x)
KEYWORD: UngetCommChar
Do not use this function under Windows 3.1 -- it causes lost
characters or even GP faults!
Submitted by Manfred Keul.^
Reference: Microsoft Knowledge Base article Q100183.
------------------------------------------------------------
WDJ SDK Annotation #66
TYPE: Win3.1
TOPIC: TabbedTextOut (3.0)
KEYWORD: TabbedTextOut
If a tab character is the last character in the string, then
all of the area to the next tab stop is filled with the
current background color. This may or may not be the
behavior you want in any given situation.
Submitted by Tim English.
------------------------------------------------------------
WDJ SDK Annotation #67
TYPE: Win3.1
TOPIC: GetRgnBox (3.0)
KEYWORD: GetRgnBox
The documentation claims GetRgnBox() returns COMPLEXREGION
when the region has overlapping borders. In fact,
GetRgnBox() apparently returns COMPLEXREGION if the region
is simply non-rectangular, whether overlapping borders are
involved or not.
Submitted by Jason Douglas.
------------------------------------------------------------
WDJ SDK Annotation #68
TYPE: Win3.1
TOPIC: DRAWITEMSTRUCT (3.0)
KEYWORD: DRAWITEMSTRUCT
The itemID field in this structure is set to a negative value
for an empty listbox or combobox. Watch out, though -- since
this field is defined to be unsigned (UINT), a statement like
this:
if(lpdis->itemID >= 0) // if listbox not empty^
// ... some code^
will always evaluate true. To check for an empty listbox or
combobox, either cast the field to int or check the high bit:
if( (int) lpdis->itemID >= 0) // this works correctly^
//... some code^
Submitted by Aaron O'Neil.
------------------------------------------------------------
WDJ SDK Annotation #69
TYPE: Win3.1
TOPIC: DDEDATA (2.x)
KEYWORD: DDEDATA
In this help topic, the description for the fResponse field
actually describes the fAckReq field, and vice versa.
Submitted by Sudhir Menon.^
Reference: Microsoft Knowledge Base article Q93372.
------------------------------------------------------------
WDJ SDK Annotation #70
TYPE: Win3.1
TOPIC: EnableCommNotification (3.1)
KEYWORD: EnableCommNotification
Due to bugs in Windows 3.1, you will probably want to always set
both cbWriteNotify and cbOutQueue to -1, thus disabling the
CN_TRANSMIT and CN_RECEIVE notifications. If you do not set
them to -1, spurious WM_COMMNOTIFY messages can be sent,
resulting in a system crash at higher baud rates.
Submitted by Manfred Keul.^
Reference: Microsoft Knowledge Base article Q101420.
------------------------------------------------------------
WDJ SDK Annotation #71
TYPE: Win3.1
TOPIC: GetMsgProc (3.1)
KEYWORD: GetMsgProc
The help file fails to mention that your hook function gets
called by PeekMessage(), not just by GetMessage(). The
documentation also contradicts itself, saying first that wParam
is undefined and later saying that wParam is NULL. The
Microsoft Knowledge Base, on the other hand, reveals that wParam
contains the PM_ flags that were used in the call to
PeekMessage(), so your message hook can, for example, determine
if the message was being removed or not with code like this:
if(wParam & PM_REMOVE)^
//... then message is being removed^
else^
//... message is not being removed^
Note that your hook may want to ignore the message if it is not
being removed, since your hook will get called again when the
same message is removed by some future call to GetMessage() or
PeekMessage().
Submitted by V. Ramachandran.^
Reference: Microsoft Knowledge Base article Q104068
------------------------------------------------------------
WDJ SDK Annotation #72
TYPE: Win3.1
TOPIC: GetInstanceData (2.x)
KEYWORD: GetInstanceData
Both the documentation and windows.h declare the second
parameter as a BYTE*. Unfortunately, that declaration is only
correct if you are using a memory model with near data (small or
medium memory models), and will be incorrect for large or huge
memory models. The correct declaration for this argument is
BYTE NEAR*.
Submitted by Martin Cooper.
------------------------------------------------------------
WDJ SDK Annotation #73
TYPE: Win3.1
TOPIC: MENUITEMTEMPLATE (3.0)
KEYWORD: MENUITEMTEMPLATE
Missing from the list of bits you can turn on in mtOption is
MF_END (0x0080), which indicates that the item terminates
the menu.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #74
TYPE: Win3.1
TOPIC: AddAtom (2.x)
KEYWORD: AddAtom
AddAtom() handles strings that begin with "#" specially:
it expects the string following the "#" to be a string
of digits, and returns an atom is value is the 16-bit
binary representation of that string of digits. Unfortunately,
if your first call to AddAtom() is with a string like "#nondigits",
it will produce a divide by zero fault. Two workarounds
are possible: either make sure your first call to AddAtom()
does not contain such a string, or call InitAtomTable()
before calling AddAtom() for the first time.
Submitted by V. Ramachandran.^
Reference: MSKB PSS ID Number: Q103036
------------------------------------------------------------
WDJ SDK Annotation #75
TYPE: Win3.1
TOPIC: DCB (2.x)
KEYWORD: DCB
When setting the BaudRate field, do not use the constant
CBR_14400; Windows 3.1's COMM.DRV has a bug that will produce
communications problems due to a bad table entry for that
constant. Instead, set BaudRate to the integer 14400 to
communicate at 14400 baud.
Submitted by Manfred Keul.^
Reference: Microsoft Knowledge Base article Q83232.
------------------------------------------------------------
WDJ SDK Annotation #76
TYPE: Win3.1
TOPIC: RegisterRoutine WinHelp macro
KEYWORD: RegisterRoutine WinHelp macro
The documentation does not reveal how to specify the return type
of the function. You do this by inserting a type-specifying
character followed by an equal sign in the third parameter
string. For example, to register FindWindow() (which takes
two far strings and returns a 16-bit unsigned integer), you
might use:
RR("USER", "FindWindow", "u=SS");
Note that if you do not specify a return type when you register
a function, you cannot use that function in an IfThen or
IfThenElse macro.
Submitted by Sudhir Menon.
------------------------------------------------------------
WDJ SDK Annotation #77
TYPE: Win3.1
TOPIC: RTF Tokens
KEYWORD: RTF Tokens
Strangely, the tokens "emc", "eml", and "emr" are
misspelled in the online help -- they should be
"ewc", "ewl", and "ewr", where the "ew" stands for
Embedded Window. Note that this are not really RTF
tokens, but literal text. The help compiler scans
for any text you have entered of the form "{ewx commands}"
in order to detect embedded window commands. Such text,
when translated by your word processor into RTF, looks
like this: "\{ewx commands\}".
Submitted by John Sawyer.
------------------------------------------------------------
WDJ SDK Annotation #78
TYPE: Win3.1
TOPIC: WM_ENTERIDLE (2.x)
KEYWORD: WM_ENTERIDLE
Note that you can elect to suppress the WM_ENTERIDLE
message for a particular modal dialog box by defining
it with the DS_NOIDLEMSG window style bit.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #79
TYPE: Win3.1
TOPIC: WM_SYSCOMMAND (2.x)
KEYWORD: WM_SYSCOMMAND
You can use this message with SC_MENUKEY to simulate the
user selecting a menu with an accelerator key. For example,
to simulate the user accessing the "File" menu, you might
use the following code:
PostMessage(hWnd, WM_SYSCOMMAND, SC_MENUKEY, MAKELPARAM('f',0));
Submitted by Jay Giganti.
------------------------------------------------------------
WDJ SDK Annotation #80
TYPE: Win3.1
TOPIC: wsprintf
KEYWORD: wsprintf
The documentation says the second parameter is an LPSTR,
but it is actually an LPCSTR (and so declared in windows.h),
so it's safe to use a string constant.
Submitted by: V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #81
TYPE: Win3.1
TOPIC: _lread (2.x)
KEYWORD: _lread
If you call _lread() to read a floppy when there is no
diskette in the drive, Windows puts up a system error
message box ("Cannot Read from Drive...") with Retry and
Cancel buttons. If the user presses the Cancel button,
_lread() returns a non-negative number, indicating success.
It should return HFILE_ERROR instead.
To avoid this error, call SetErrorMode(SEM_NOOPENFILEERRORBOX)
before calling _lread(), then it will correctly return -1 on
failure.
Submitted by: V. Ramachandran.^
Reference: MSDN PSS ID No. Q111587.
------------------------------------------------------------
WDJ SDK Annotation #82
TYPE: Win3.1
TOPIC: WM_COMPAREITEM (3.0)
KEYWORD: WM_COMPAREITEM
The documentation for WM_COMPAREITEM says that the parent of
owner-drawn listboxes with the LBS_SORT (or CBS_SORT) styles
will get this message in order to determine the relative
position. However, Windows will not send the WM_COMPAREITEM
message if the LBS_HASSTRINGS style bit is set, even if it
is an owner-drawn listbox with the LBS_SORT style. The same
is true for comboboxes.
Submitted by: V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #83
TYPE: Win3.1
TOPIC: DOCINFO (3.1)
KEYWORD: DOCINFO
The documentation fails to point out that lpszOutput is
limited to 32 characters, including the null terminating
byte. If you use a string longer than that, the trailing
characters will be ignored. For example, if you use a
string containing the too-long path:
c:\usr\ts\issues\pending\12345678\abcdefgh.out
the actual file that gets created will be:
c:\usr\ts\issues\pending\123456
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #84
TYPE: Win3.1
TOPIC: SetAbortProc function
KEYWORD: SetAbortProc
SetAbortProc() returns a negative value, which is documented
as indicating failure. However, the return value from
SetAbortProc does not indicate success or failure of the
function, so don't depend on the return value for anything.
Submitted by: V. Ramachandran.^
Reference: MSDN PSS ID No. Q109540.
------------------------------------------------------------
WDJ SDK Annotation #85
TYPE: Win3.1
TOPIC: BN_DISABLE (2.x)
KEYWORD: BN_DISABLE
The documentation claims the button sends this notification
whenever it gets disabled. In fact, Windows 3.1 buttons do
not appear to ever send this notification!
Submitted by: V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #86
TYPE: Win3.1
TOPIC: BN_DOUBLECLICKED (2.x)
KEYWORD: BN_DOUBLECLICKED
The documentation fails to point out that this notification
is only sent for buttons that have the BS_OWNERDRAW or
BS_RADIOBUTTON styles. No other types of buttons generate
this notification
Submitted by: V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #87
TYPE: Win3.1
TOPIC: WM_DROPFILES (3.1)
KEYWORD: WM_DROPFILES
Documentation for the undocumented handle has since been
published by Microsoft in Microsoft Systems Journal. This
handle points to a structure like this:
typedef struct {^
int wSize; // Number of bytes in this structure^
POINT ptMousePos; // Mouse position^
BOOL fInNonClientArea;// TRUE if mouse was in client area^
// Pathnames begin after structure each one zero-terminated^
// Zero-length pathname used to indicate the end^
} DROPFILESTRUCT, FAR *LPDROPFILESTRUCT;^
The Win32 version of this structure is slightly different. The
first field becomes a 4-byte rather than a 2-byte integer, and
the structure contains an additional BOOL field at the end that
is TRUE if the pathnames are in Unicode rather than ANSI
strings.
Submitted by V. Ramachandran.^
Reference: May/June 1992 Microsoft Systems Journal^
February 1994 Microsoft Systems Journal
------------------------------------------------------------
WDJ SDK Annotation #87
TYPE: Win32
TOPIC: WM_DROPFILES
KEYWORD: WM_DROPFILES AND Parameters
Documentation for the undocumented handle has since been
published by Microsoft in Microsoft Systems Journal. This
handle points to a structure like this:
typedef struct {^
int wSize; // Number of bytes in this structure^
POINT ptMousePos; // Mouse position^
BOOL fInNonClientArea;// TRUE if mouse was in client area^
// Pathnames begin after structure each one zero-terminated^
// Zero-length pathname used to indicate the end^
} DROPFILESTRUCT, FAR *LPDROPFILESTRUCT;^
The Win32 version of this structure is slightly different. The
first field becomes a 4-byte rather than a 2-byte integer, and
the structure contains an additional BOOL field at the end that
is TRUE if the pathnames are in Unicode rather than ANSI
strings.
Submitted by V. Ramachandran.^
Reference: May/June 1992 Microsoft Systems Journal^
February 1994 Microsoft Systems Journal
------------------------------------------------------------
WDJ SDK Annotation #88
TYPE: Win3.1
TOPIC: List box messages
KEYWORD: List box messages
Internally, listboxes maintain two 32-bit DWORDs for each
listbox item. The first DWORD points to the text for the item
and the second DWORD contains whatever custom data you would
like; you can get it via LB_GETITEMDATA or set it via
LB_SETITEMDATA. Some messages refer to one or the other of
these DWORDs, depending on whether the LBS_HASSTRINGS style is
set:
Message LBS_HASSTRINGS? Refers to:^
==========================================================^
LB_ADDSTRING Yes text pointer (lParam)^
LB_ADDSTRING No custom data (lParam)^
LB_INSERTSTRING Yes text pointer (lParam)^
LB_INSERTSTRING No custom data (lParam)^
LB_GETTEXT Yes returns text pointer^
LB_GETTEXT No returns custom data^
LB_GETITEMDATA either returns custom data^
LB_SETITEMDATA either sets custom data (lParam)^
WM_DRAWITEM either custom data (in itemData field)^
In other words, if LBS_HASSTRINGS is not set, you cannot access
the normal text pointer -- all messages operate on the custom
data. But if LBS_HASSTRINGS is set, you can access both the
normal text as well as the extra DWORD of custom data.
Submitted by V. Ramachandran
------------------------------------------------------------
WDJ SDK Annotation #89
TYPE: Win3.1
TOPIC: SetTimer (2.x)
KEYWORD: SetTimer
Though the documentation does not mention this, you can
change the timer interval after you create the timer. If
you call SetTimer() with a window handle and a timer ID
equal to an existing timer and specify a different time
interval, SetTimer() updates the timer to the new time
interval.
Example:
Use the following line to set a timer to a particular time
interval.
UINT nTimerID = SetTimer (hWnd, TIMER_ID, TIME_INTERVAL, NULL)
Calling the following line will reset the timer to twice the
time interval.
nTimerID = SetTimer (hWnd, TIMER_ID, 2*TIME_INTERVAL, NULL)
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #90
TYPE: Win3.1
TOPIC: TranslateAccelerator (2.x)
KEYWORD: TranslateAccelerator
Contrary to the documentation, both WM_INITMENU and
WM_INITMENUPOPUP get sent, even if the menu item is disabled,
and even if the window is minimized and the keystroke matches no
menu items.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #91
TYPE: Win3.1
TOPIC: GetPrivateProfileInt (3.0)
KEYWORD: GetPrivateProfileInt
The documentation says you must use a positive integer
in the range 0 through 32,767 (0x7FFF) for the third
argument, which is the default value the function returns
if it cannot locate the desired entry in the .ini file.
In fact, you can pass any legal integer value for this
parameter -- it's just that since the function's return
type is defined to be UINT, you must cast the result to
int if you want to treat the result as a negative number.
For example, the following code works correctly, despite
what the documentation says:
int Val = (int)GetPrivateProfileInt(
"MyLib", "Debug", -1, "MyLib.ini");
if(Val == -1)
/* then no such entry found */
------------------------------------------------------------
WDJ SDK Annotation #92
TYPE: Win32
TOPIC: WM_NOTIFY
KEYWORD: WM_NOTIFY AND "See also"
If your dialog procedure handles a WM_NOTIFY that requires a
return value, note that you MUST both return a non-zero
value (to indicate to the dialog manager that you wish to
specify a return value for the message) AND store the
desired return value for the message in the window field
DWL_MSGRESULT. The standard Windows header file windowsx.h
provides a macro called SetDlgMsgResult() that makes this
easy:
#include <windowsx.h>
//...
case WM_NOTIFY :
{
NMHDR* Head = (NMHDR*)lParam;
if(Head->code == LVN_ENDLABELEDIT)
// allow user to edit listview labels
return SetDlgMsgResult(Dialog, WM_NOTIFY, TRUE);
}
------------------------------------------------------------
WDJ SDK Annotation #92
TYPE: Win32
TOPIC: LVN_ENDLABELEDIT
KEYWORD: LVN_ENDLABELEDIT AND Parameters
If your dialog procedure handles a WM_NOTIFY that requires a
return value (as this one does), note that you MUST both
return a non-zero value (to indicate to the dialog manager
that you wish to specify a return value for the message) AND
store the desired return value for the message in the window
field DWL_MSGRESULT. The standard Windows header file
windowsx.h provides a macro called SetDlgMsgResult() that
makes this easy:
#include <windowsx.h>
//...
case WM_NOTIFY :
{
NMHDR* Head = (NMHDR*)lParam;
if(Head->code == LVN_ENDLABELEDIT)
// allow user to edit listview labels
return SetDlgMsgResult(Dialog, WM_NOTIFY, TRUE);
}
------------------------------------------------------------
WDJ SDK Annotation #92
TYPE: Win32
TOPIC: LVN_BEGINLABELEDIT
KEYWORD: LVN_BEGINLABELEDIT AND Parameters
If your dialog procedure handles a WM_NOTIFY that requires a
return value (as this one does), note that you MUST both
return a non-zero value (to indicate to the dialog manager
that you wish to specify a return value for the message) AND
store the desired return value for the message in the window
field DWL_MSGRESULT. The standard Windows header file
windowsx.h provides a macro called SetDlgMsgResult() that
makes this easy:
#include <windowsx.h>
//...
case WM_NOTIFY :
{
NMHDR* Head = (NMHDR*)lParam;
if(Head->code == LVN_BEGINLABELEDIT)
// allow user to edit listview labels
return SetDlgMsgResult(Dialog, WM_NOTIFY, FALSE);
}
------------------------------------------------------------
WDJ SDK Annotation #93
TYPE: Win3.1
TOPIC: GetWindowText
KEYWORD: GetWindowText
GetWindowText() and GetDlgItemText() will not work when
applied to a standard edit control that belongs to another
application. The problem is that GetWindowText() and
GetDlgItemText() attempt to optimize by directly examining
the window caption of the target window. An edit control
stores an empty string in its caption, not the edit control
text, so this fails. You can avoid this bug by sending a
WM_GETTEXT explicitly:
HWND OtherEdit;
char Buffer[256];
SendMessage(OtherEdit, WM_GETTEXT,
sizeof(Buffer), (LPARAM)Buffer);
------------------------------------------------------------
WDJ SDK Annotation #93
TYPE: Win3.1
TOPIC: GetDlgItemText
KEYWORD: GetDlgItemText
GetWindowText() and GetDlgItemText() will not work when
applied to a standard edit control that belongs to another
application. The problem is that GetWindowText() and
GetDlgItemText() attempt to optimize by directly examining
the window caption of the target window. An edit control
stores an empty string in its caption, not the edit control
text, so this fails. You can avoid this bug by sending a
WM_GETTEXT explicitly:
HWND OtherEdit;
char Buffer[256];
SendMessage(OtherEdit, WM_GETTEXT,
sizeof(Buffer), (LPARAM)Buffer);
------------------------------------------------------------
WDJ SDK Annotation #94
TYPE: Win32
TOPIC: LVM_GETCOLUMNWIDTH
KEYWORD: LVM_GETCOLUMNWIDTH AND Parameters
The documentation claims that this message returns the
column width if successful, "or zero otherwise". In fact,
if you specify an invalid column number, this function
returns garbage. Therefore, you cannot use this message to
count the number of columns in a listview control. The
associated message, LVM_GETCOLUMN, does correctly return
zero when passed an invalid column number, so you can use
LVM_GETCOLUMN to determine the number of columns in a
listview control.
------------------------------------------------------------
WDJ SDK Annotation #95
TYPE: Win3.1
TOPIC: SystemParametersInfo (3.1)
KEYWORD: SystemParametersInfo
The documentation says that the screen saver time out
(SPI_GETSCREENSAVETIMEOUT) is specified in milliseconds. In
fact, the value returned is in seconds.
Submitted by: Carlton Guc
------------------------------------------------------------
WDJ SDK Annotation #96
TYPE: Win32
TOPIC: LVN_ENDLABELEDIT
KEYWORD: LVN_ENDLABELEDIT AND Parameters
The documentation claims that there is no return value for
this message. In fact, you should return FALSE if you want
to reject the user's editing, or TRUE if you want to allow
the changes to the listview item. If you are handling this
notification inside a dialog procedure, remember that you
must return a non-zero result AND store the message result
(either TRUE or FALSE) in DWL_MSGRESULT, using either
SetWindowLong() or the SetDlgMsgResult() macro (defined in
windowsx.h).
Submitted by: Poul A. Costinsky
------------------------------------------------------------
WDJ SDK Annotation #98
TYPE: Win32
TOPIC: RegSetValueEx
KEYWORD: RegSetValueEx AND "See also"
For string-based data types, such as REG_SZ, this function
behaves differently under Win95 and NT. Under Win95, if you
pass a value of "abcd" and a length of 4, the function will
actually append a null byte, and if you retrieve the value
later, you will find it has a length of 5. Under NT, this
function stores exactly what you tell it to store.
Submitted by Paula Tomlinson.
------------------------------------------------------------
WDJ SDK Annotation #97
TYPE: Win32
TOPIC: LVN_ITEMCHANGING
KEYWORD: LVN_ITEMCHANGING AND Parameters
The documentation incorrectly claims that you have to return
TRUE to allow the change, or FALSE to prevent it. In fact,
you have to return FALSE to allow the change or TRUE to
prevent it.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #99
TYPE: Win32
TOPIC: LV_DISPINFO
KEYWORD: LV_DISPINFO AND Parameters
The documentation says you can set the LVIF_DI_SETITEM flag
in the mask member to have Windows store the string and not
ask for it again. It fails to point out that this only
works for subitem 0 (the first column), so you would still
have to handle requests for the text of the other columns.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #100
TYPE: Win32
TOPIC: LVM_EDITLABEL
KEYWORD: LVM_EDITLABEL AND Parameters
Note that the listview control implements in-place editing
by creating an edit control on the fly. Unfortunately, it
assigns that edit control a child ID of IDOK, which means
that the parent of the listview control will receive edit
control notifications that it might not expect. For
example, if your listview control is in a dialog box, and
your dialog procedure contains code like this:
// inside WM_COMMAND handler...
if(ControlId == IDOK)
EndDialog(Dialog, TRUE);
Then it may terminate the dialog when the user starts
editing a listview item (since the transient edit control
will send notifications like EN_CHANGE, with a control ID of
IDOK). The above code should read:
// inside WM_COMMAND handler...
if(ControlId == IDOK && NotifyCode == BN_CLICKED)
EndDialog(Dialog, TRUE);
to be safe.
------------------------------------------------------------
WDJ SDK Annotation #101
TYPE: Win3.1
TOPIC: GetWindowTextLength (2.x)
KEYWORD: GetWindowTextLength
Due to a bug in Windows 3.1, both GetWindowTextLength() and
WM_GETTEXTLENGTH return -1 if you use it on a combobox of
style CBS_DROPDOWNLIST.
Submitted by Mircea Neacsu
------------------------------------------------------------
WDJ SDK Annotation #102
TYPE: Win32
TOPIC: LB_ADDSTRING
KEYWORD: LB_ADDSTRING AND Parameters
If you are planning to add a large number (more than 100) of
strings by calling LB_ADDSTRING, LB_INSERTSTRING, LB_DIR, or
LB_ADDFILE, consider first sending the new Win32 message
LB_INITSTORAGE to give the listbox a chance to preallocate
memory, thus speeding up the process.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #102
TYPE: Win32
TOPIC: LB_ADDSTRING
KEYWORD: LB_ADDSTRING AND Parameters
If you are planning to add a large number (more than 100) of
strings by calling LB_ADDSTRING, LB_INSERTSTRING, LB_DIR, or
LB_ADDFILE, consider first sending the new Win32 message
LB_INITSTORAGE to give the listbox a chance to preallocate
memory, thus speeding up the process.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #103
TYPE: Win32
TOPIC: LoadString
KEYWORD: LoadString AND "See also"
Even though resource strings are stored as Unicode for both
Win95 and NT programs, Win95 does not provide an
implementation of the Unicode version of LoadString()
(LoadStringW()). This usually trips up NT programmers who
want to create a single .exe for both operating systems and
yet still use Unicode under NT. In that case, you must at
runtime detect that you are running under Win95 and, in that
case, explicitly call LoadStringA(). Otherwise, if you have
compiled with _UNICODE defined, LoadString() will expand
into LoadStringW(), which is just a stub that fails under
Win95.
Submitted by Paula Tomlinson.
------------------------------------------------------------
WDJ SDK Annotation #104
TYPE: Win32
TOPIC: LVN_DELETEITEM
KEYWORD: LVN_DELETEITEM AND Parameters
The documentation implies that this notification
arrives after the item is deleted. In fact, it
arrives before the item is deleted from the listview
control.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #105
TYPE: Win32
TOPIC: IsWindow
KEYWORD: IsWindow AND Parameters
The documentation claims this function returns TRUE if the
given handle is a valid window handle. That was true under
Windows 3.x and is true under Windows NT, but Windows 95
returns a large non-zero value that is not equal to 1 (nor
is it equal to the window handle). In an un-indexed help
topic in the initial Win95 SDK, Microsoft reveals that
Win95 functions with BOOL return types are only guaranteed
to return non-zero when the documentation claims they
return TRUE. Windows NT appears to behave as documented.
Submitted by: David Lowndes
------------------------------------------------------------
WDJ SDK Annotation #105
TYPE: Win32
TOPIC: GetClientRect
KEYWORD: GetClientRect AND "See also"
The documentation claims this function returns TRUE if the
given handle is a valid window handle. That was true under
Windows 3.x and is true under Windows NT, but Windows 95
returns a large non-zero value that is not equal to 1 (nor
is it equal to the window handle). In an un-indexed help
topic in the initial Win95 SDK, Microsoft reveals that
Win95 functions with BOOL return types are only guaranteed
to return non-zero when the documentation claims they
return TRUE. Windows NT appears to behave as documented.
Submitted by: Ron Scott
------------------------------------------------------------
WDJ SDK Annotation #106
TYPE: Win32
TOPIC: WM_GETDLGCODE
KEYWORD: WM_GETDLGCODE AND Parameters
The documentation WM_GETDLGCODE states that this message has
no parameters. But the truth is that if the user presses a
key, lParam will contain a pointer to a MSG structure
containing information about the event that made Windows send
the WM_GETDLGCODE message. This is indirectly documented in
windowsx.h, where the HANDLE_WM_GETDLGCODE() macro passes
two arguments to the handler: the window handle and (MSG
FAR*)(lParam).
Submitted by: Patrick Tennberg
Reference: Microsoft Knowledge Base article Q83302
------------------------------------------------------------
WDJ SDK Annotation #107
TYPE: Win32
TOPIC: DBT_DEVICEQUERYREMOVE
KEYWORD: DBT_DEVICEQUERYREMOVE AND Parameters
The documentation incorrectly says that you should return
FALSE if you want to veto the device removal. In fact, you
have to return BROADCAST_QUERY_DENY; returning FALSE will
allow the device removal to proceed.
Submitted by Paula Tomlinson.
------------------------------------------------------------
WDJ SDK Annotation #108
TYPE: Win3.1
TOPIC: LZOpenFile
KEYWORD: LZOpenFile
However, if lpszFile contains only a filename and extension
(i.e. no path is specified), then LZOpenFile() use the same
searching logic as OpenFile(). If no file with the matching
name (and extension) is found, then it searches for the
compressed filename. The compressed file has a _ as the
last character (e.g., the compressed version of "readme.txt"
is "readme.tx_"). Therefore if you use LZOpenFile() to open
a file called "readme.txt", it searches as follows:
1) it looks for "readme.txt" using the same search
algorithm as OpenFile().
2) if the file was not found, it uses the same
algorithm to search for "readme.tx_".
That means LZOpenFile() might open a "readme.tx_" file from
a directory other than the one you expected. Even if you
specify the complete filename (such as
"c:\demo\readme.txt"), LZOpenFile() first searches for the
specified file, and if the specified filename is not found,
it searches for the compressed file in the same directory
("c:\demo\readme.tx_").
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #109
TYPE: Win32
TOPIC: SetCapture
KEYWORD: SetCapture AND Parameters
This help topic does not document the fact that when the
mouse is captured, menu hotkeys (for example, Alt+F for
accessing the File menu) and other keyboard accelerators do
not work (ex: Alt+F4). This is because DefWindowProc()
handles the WM_SYSCHAR and WM_SYSCOMMAND messages
differently if the mouse has been captured (by any window).
DefWindowProc() processes the WM_SYSCHAR message to check if
the pressed key is a menu hotkey (Alt+F for example). If it
is, then it causes the menu to drop down. However, if the
mouse is captured, it does not do the above action.
Whenever DefWindowProc() sees a WM_SYSCOMMAND and finds that
the mouse is captured, then it does nothing.
Submitted by V. Ramachandran.
------------------------------------------------------------
WDJ SDK Annotation #110
TYPE: Win32
TOPIC: RegCreateKey
KEYWORD: RegCreateKey AND "See also"
The documentation for RegCreateKey(), RegCreateKeyEx(),
RegOpenKey(), and RegOpenKeyEx() all list several predefined
handles you can use, such as HKEY_CURRENT_USER. However,
they fail to document the predefined key
HKEY_CURRENT_CONFIG, which has a structure similar to the
registry tree under HKEY_LOCAL_MACHINE, but is for storing
information specific to the current hardware profile.
Submitted by Paula Tomlinson.
------------------------------------------------------------
WDJ SDK Annotation #111
TYPE: Win32
TOPIC: CreateFile
KEYWORD: CreateFile AND "See also"
The documentation claims CreateFile() returns a handle that
can be used to access the object. However, under both NT
and Win95, CreateFile() will appear to succeed and return a
valid handle if you attempt to open a file with
GENERIC_WRITE permissions on a read-only medium (e.g.,
protected floppy or CD-ROM). If you then try to perform a
write with the returned handle, that will fail.
Submitted by: David Lowndes
------------------------------------------------------------
WDJ SDK Annotation #112
TYPE: Win32
TOPIC: GetWindowText
KEYWORD: GetWindowText AND "See Also"
The third argument is the "maximum numbers of characters to
copy". It may not be clear that this number must include
the NULL byte so, for example, it never makes sense to set
this argument to 1 since all you could get back is a NULL
byte. If you want to use GetWindowText() to retrieve a
single character (e.g., from an edit control), you would
have to specify a length of 2 -- one for the character and
one for the terminating NULL byte.
Submitted by: Tony Yuricich
------------------------------------------------------------
WDJ SDK Annotation #113
TYPE: Win32
TOPIC: keybd_event
KEYWORD: keybd_event AND "See also"
You can use this function to toggle keys such as the Caps
Lock, Scroll Lock, and Num Lock. Unfortunately, though
toggling these three keys works correctly under NT, you
cannot use this function to toggle the Num Lock key under
Win95.
------------------------------------------------------------
WDJ SDK Annotation #114
TYPE: Win3.1
TOPIC: WM_CTLCOLOR (2.x)
KEYWORD: WM_CTLCOLOR
The documentation incorrectly states that "the return value
from this message has no effect on a button with the
BS_PUSHBUTTON or BS_DEFPUSHBUTTON style." In fact, returning
a brush handle in response to this message appears to
determine the color of the pushbutton window background,
which is visible as the tiny areas in the corners of the
pushbutton window. Note that under Windows 95, pushbuttons
fill the entire client area of their windows, thus hiding
the window background from view.
Submitted by: Forest Wilkinson
------------------------------------------------------------
WDJ SDK Annotation #115
TYPE: Win32
TOPIC: GlobalDeleteAtom
KEYWORD: GlobalDeleteAtom AND "See also"
The documentation for GlobalDeleteAtom states:
"The only way to ensure that an atom has been deleted from the
atom table is to call this function repeatedly until it fails."
Unfortunately, a 32-bit program running under Win NT 3.51 never fails,
making for an infinite loop (Windows 95 functions as documented).
Microsoft says this may be fixed in the next release (NT 4.0).
Submitted by Ken Brown
------------------------------------------------------------
WDJ SDK Annotation #116
TYPE: Win32
TOPIC: LB_ADDSTRING
KEYWORD: LB_ADDSTRING AND "See also"
If your listbox has the WS_HSCROLL style, and if you are
adding a string wider than the listbox, you may have to send
a LB_SETHORIZONTALEXTENT message to make the horizontal
scrollbar appear. The listbox does not automatically check
each newly added string and add the horizontal scrollbar
when a too-wide string is added or inserted.
------------------------------------------------------------
WDJ SDK Annotation #117
TYPE: Win32
TOPIC: LB_DIR
KEYWORD: LB_DIR AND "See also"
If you pass a long filename to LB_DIR, it works
under NT 3.51, but fails under Win95 because it
relies on the 16-bit listbox which was not changed
to handle long filenames. You can avoid the error
by first translating the filename to a short filename
by calling GetShortPathName(). The LB_DIR will not
fail, but it will still display only the short versions
of any long filenames in the subdirectory.
Reference: Microsoft Knowledge Base article Q131286
------------------------------------------------------------
WDJ SDK Annotation #118
TYPE: Win32
TOPIC: ReadFile
KEYWORD: ReadFile AND "See also"
The documentation correctly points out that Win95
does not support OVERLAPPED I/O. However, it incorrectly
states that you must pass a pointer to a structure of
type OVERLAPPED if the file was created (or opened)
with the flag FILE_FLAG_OVERLAPPED. In fact, if you
pass a pointer (rather than NULL) under Windows 95,
ReadFile() returns FALSE, and GetLastError() returns
ERROR_INVALID_PARAMETER, whether or not the file
was created/opened with the FILE_FLAG_OVERLAPPED
flag. That means that if you want to code a call
to ReadFile() that works correctly for both
synchronous and asynchronous I/O, you must detect
at runtime that you're running under Win95 and
treat that case differently.
-----------------------------------------------------------------------
WDJ SDK Annotation #119
TYPE: Win32
TOPIC: WinMain
KEYWORD: WinMain AND "See also"
Note that the string passed in lpCmdLine is not the same as
the string returned by GetCommandLine(). The string in
lpCmdLine contains the command line arguments only, but
GetCommandLine() returns the program name followed by the
arguments.
If you specify the following command: 'winword abc.doc', and
winword exists in d:\msoffice\winword.exe, lpCmdLine will
contain 'abc.doc', while GetCommandLine will return
'"d:\msoffice\winword.exe" abc.doc' Note the double quotes
around the exe name.
Submitted by Phil Rodgers.
----------------------------------------------------------------------
WDJ SDK Annotation #119
TYPE: Win32
TOPIC: GetCommandLine
KEYWORD: GetCommandLine AND "See also"
Note that the string passed in the lpCmdLine parameter to
WinMain is not the same as the string returned by
GetCommandLine(). GetCommandLine() returns the complete
program name enclosed in double quotes, followed by the
arguments; whereas the lpCmdLine parameter of WinMain
contains the command line arguments only.
If you specify the following command: 'winword abc.doc', and
winword exists in d:\msoffice\winword.exe, lpCmdLine will
contain 'abc.doc', while GetCommandLine will return
'"d:\msoffice\winword.exe" abc.doc' Note the double quotes
around the exe name.
Submitted by Phil Rodgers.
----------------------------------------------------------------------
WDJ SDK Annotation #120
TYPE: Win32
TOPIC: ShellAbout
KEYWORD: ShellAbout AND "See also"
The documentation says that in Windows 95 ShellAbout will
prepend "Microsoft Windows" to the title of the application.
This is not true. Actually, this function prepends only
"Microsoft", so if your app is called "MyApp", the title
will read "Microsoft MyApp".
Submitted by Luis A. Ramos.
----------------------------------------------------------------------
WDJ MFC Annotation #121
TYPE: MFC 4
TOPIC: CPropertySheet::SetTitle
KEYWORD: SetTitle AND CPropertySheet
The parameters to this function are interchanged: it should
actually read:
void SetTitle (LPCTSTR lpszText, UINT nStyle);
Submitted by Margaret M. O'Connell.
----------------------------------------------------------------------
WDJ MFC Annotation #122
TYPE: MFC 1.5x
TOPIC: CCmdTarget::GetIDispatch
KEYWORD: GetIDispatch AND CCmdTarget
The MFC 1.5x documentation incorrectly states that this
function takes no parameters. It should read:
LPDISPATCH GetIDispatch (BOOL bAddRef)
bAddRef - specifies whether to increment
the reference count for the object.
This has been corrected in the MFC 4.0 documentation.
Submitted by V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #123
TYPE: Win16
TOPIC: LB_SELECTSTRING
KEYWORD: LB_SELECTSTRING
win31wh.hlp fails to mention that this message works only
with single select listboxes. For multi-select listboxes it
returns LB_ERR.
Submitted by Dino Esposito.
----------------------------------------------------------------------
WDJ SDK Annotation #124
TYPE: Win32
TOPIC: AdjustWindowRect
KEYWORD: AdjustWindowRect AND "See also"
The documentation for AdjustWindowRect() and
AdjustWindowRectEx() has a number of problems.
1. Though the documentation says that window titles and
borders are not taken into account, the function does
account for these styles.
2. Add 1 to the rect.bottom returned by this function.
There is a one-off error in the y direction.
3. The meaning of the rect parameter is not well explained.
The input to AdjustWindowRectEx is the window coordinates of
the top-left and bottom-right corners of the desired client
area. AdjustWindowRectEx inflates the specified rectangle
to include the caption, border and other non-client objects
specified by the style parameter.
Reference: MSDN Dr.GUI #10 - Calculated Client Window Size.
Submitted by Etay Szekely.
----------------------------------------------------------------------
WDJ SDK Annotation #124
TYPE: Win32
TOPIC: AdjustWindowRectEx
KEYWORD: AdjustWindowRectEx AND "See also"
The documentation for AdjustWindowRect() and
AdjustWindowRectEx() has a number of problems.
1. Though the documentation says that window titles and
borders are not taken into account, they function does
account for these styles.
2. Add 1 to the rect.bottom returned by this function.
There is a one-off error in the y direction.
3. The meaning of the rect parameter is not well explained.
The input to AdjustWindowRectEx is the window coordinates of
the top-left and bottom-right corners of the desired client
area. AdjustWindowRectEx inflates the specified rectangle
to include the caption, border and other non-client objects
specified by the style parameter.
Reference: MSDN Dr.GUI #10 - Calculated Client Window Size.
Submitted by Etay Szekely.
----------------------------------------------------------------------
WDJ MFC Annotation #125
TYPE: MFC 3.1 and 3.2
TOPIC: CImageList::DeleteObject
KEYWORD: DeleteObject AND "See also" NOT HRESULT
VC++ 2.1 and 2.2 help files incorrectly documented this
function to delete image lists, while it actually never
existed. The correct function to delete an image list is
CImageList::DeleteImageList(); it returns non-zero if
successful and zero if it fails.
This error is corrected in the VC++ 4.0 documentation.
Submitted by Barry Tannenbaum.
----------------------------------------------------------------------
WDJ SDK Annotation #126
TYPE: Win32
TOPIC: AVIFileOpen
KEYWORD: AVIFileOpen AND "See also"
The documentation specifies that using the OF_CREATE flag
will cause an existing file to be truncated to zero length.
In reality, it has no effect: the file length remains the
same, and the old data is intact once the file is closed.
Submitted by Tim Lesher.
----------------------------------------------------------------------
WDJ SDK Annotation #127
TYPE: Win16
TOPIC: CBTProc
KEYWORD: CBTProc
The CBTProc documentation fails to mention that you can
return 0 to allow the operation and 1 to prevent it for
HCBT_SETFOCUS notification also. The documentation has been
corrected in the Win32 help file.
Submitted by V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #128
TYPE: Win32
TOPIC: GetDialogBaseUnits
KEYWORD: GetDialogBaseUnits AND "See also"
GetDialogBaseUnits() does not return correct dialog base
units if the dialog is not using the system font. Use the
following function instead:
DWORD WDJ_GetDialogBaseUnits (HWND Dialog)
{
int BaseX, BaseY;
RECT R;
SetRect (&R, 0, 0, 4, 8);
MapDialogRect (Dialog, &R);
BaseX = R.right;
BaseY = R.bottom;
return (DWORD)MAKELONG (BaseX, BaseY);
}
Reference: p54, January 1996 Windows Developer's Journal.
----------------------------------------------------------------------
WDJ SDK Annotation #129
TYPE: Win32
TOPIC: GetShortPathName
KEYWORD: GetShortPathName AND "See also"
The documentation fails to mention that this function returns an error
if the specified long path (first parameter) is invalid.
Submitted by Ken Brown.
----------------------------------------------------------------------
WDJ MFC Annotation #130
TYPE: MFC
TOPIC: CCheckListBox::Create
KEYWORD: CCheckListBox::Create AND "See also"
The documentation mentions that the dwStyle parameter could be any
of the specified listbox styles. However, the dwStyle parameter should
NOT be LBS_MULTICOLUMN or LBS_USETABSTOPS. Morever, you need to specify
LBS_OWNERDRAWFIXED and LBS_HASSTRINGS. You can specify
LBS_OWNERDRAWVARIABLE instead of LBS_OWNERDRAWFIXED, but then you need to
override CCheckListBox::DrawItem, otherwise the debug version will ASSERT.
Submitted by Sudhir Menon.
----------------------------------------------------------------------
WDJ SDK Annotation #131
TYPE: Win32
TOPIC: TBBUTTON
KEYWORD: TBBUTTON AND "See also"
The structure is actually defined as follows in commctrl.h. Under Win32
2 extra padding bytes are added.
typedef struct _TBBUTTON {
int iBitmap;
int idCommand;
BYTE fsState;
BYTE fsStyle;
#ifdef _WIN32
BYTE bReserved[2];
#endif
DWORD dwData;
int iString;
} TBBUTTON, NEAR* PTBBUTTON, FAR* LPTBBUTTON;
typedef const TBBUTTON FAR* LPCTBBUTTON;
Submitted by Eric Heimburg.
----------------------------------------------------------------------
WDJ SDK Annotation #132
TYPE: Win32
TOPIC: EM_POSFROMCHAR
KEYWORD: EM_POSFROMCHAR AND "See also"
The documentation for the wParam, lParam and return value is
completely wrong. It should be as follows:
wParam - address of point structure to retrieve the coordinates
lParam - zero based index of character
Return value - not used
Reference: PSS Q137805
Submitted by Fred Heidrich.
----------------------------------------------------------------------
WDJ SDK Annotation #133
TYPE: Win32
TOPIC: EM_CHARFROMPOS
KEYWORD: EM_CHARFROMPOS AND "See also"
The documentation for the lParam and return value is wrong. It
should be as follows:
wParam - 0 (not used)
lParam - Specifies a pointer to a POINT structure that contains the
coordinates for the character position wanted.
Return value - specifies the character index
Reference: PSS Q137805
Submitted by Fred Heidrich.
----------------------------------------------------------------------
WDJ MFC Annotation #134
TYPE: MFC 4.0
TOPIC: CEdit::PosFromChar
KEYWORD: CEdit::PosFromChar AND "See also"
The MFC wrapper internally calls the EM_POSFROMCHAR function passing
the documented values. Unfortunately, there is a documentation error in
EM_POSFROMCHAR, and therefore PosFromChar will not work correctly.
Read SDK Annotation #132 or PSS Q137805 for more details.
This error has been corrected in MFC 4.1
----------------------------------------------------------------------
WDJ MFC Annotation #135
TYPE: MFC 4.0
TOPIC: CEdit::CharFromPos
KEYWORD: CEdit::CharFromPos AND "See also"
The MFC wrapper internally calls the EM_CHARFROMPOS function passing
the documented values. Unfortunately, there is a documentation error in
EM_CHARFROMPOS, and therefore CharFromPos will not work correctly.
Read SDK Annotation #133 or PSS Q137805 for more details.
This error has been corrected in MFC 4.1
----------------------------------------------------------------------
WDJ SDK Annotation #136
TYPE: Win32
TOPIC: BM_SETIMAGE
KEYWORD: BM_SETIMAGE AND "See also"
The documentation for wParam is incorrect. wParam actually specifies the
type of handle passed in lParam. It must be set either IMAGE_BITMAP or
IMAGE_ICON.
Also, this message will work only on buttons created with the
BS_BITMAP or BS_ICON style.
Reference: PSS Q125673
Submitted by Paula Tomlinson.
----------------------------------------------------------------------
WDJ SDK Annotation #137
TYPE: Win16
TOPIC: GetOpenFileName
KEYWORD: GetOpenFileName
In 16-bit Windows, if you call GetOpenFileName with a string buffer of 10
and set nMaxFile to 10, and the user selected a file whose full path name
is 10 characters long, Windows appends a NULL character at the 11th byte
and returns the filename. This behaviour remains in Win95.
Therefore, if you set nMaxFile to n, specify a buffer of length n+1 before
calling this function.
Reference: March TechNet CD Q137194
Submitted by: V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #137
TYPE: Win32
TOPIC: GetOpenFileName
KEYWORD: GetOpenFileName AND "See also"
In 16-bit Windows, if you call GetOpenFileName with a string buffer of 10
and set nMaxFile to 10, and the user selected a file whose full path name
is 10 characters long, Windows appends a NULL character at the 11th byte
and returns the filename. This behaviour remains in Win95.
Therefore, if you set nMaxFile to n, specify a buffer of length n+1 before
calling this function.
Reference: March TechNet CD Q137194
Submitted by: V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #138
TYPE: Win32
TOPIC: LB_DIR
KEYWORD: LB_DIR AND "See also"
Sending a LB_DIR message to a listbox that specifies a long filename in
the lParam returns LB_ERR in Windows 95, but works fine under Windows
NT 3.51
In order to work around this bug, call GetShortPathName on the long
filename and pass the short filename to LB_DIR.
Reference: March TechNet CD Q131286
Submitted by: V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #139
TYPE: Win16
TOPIC: EM_SETSEL
KEYWORD: EM_SETSEL
The SDK documentation mentions that if wParam is 0, the caret is scrolled
into view, and if wParam is 1 it is not scrolled into view. However,
this parameter is not used for single line edit controls.
Also, the order of the start and end positions specified in the lParam
is not respected by single line edit controls.
Both wParam and lParam work as documented for multiline edit controls.
Reference: MSDN PSS Q102641, Q64758.
Submitted by: V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #140
TYPE: Win32
TOPIC: STGM
KEYWORD: STGM AND "See also"
The documentation fails to mention that for all storage and stream
creation functions, you HAVE to specify a share mode flag. For example,
a call to StgCreateDocfile with STGM_CREATE | STGM_READWRITE will fail;
while passing STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE will
work correctly.
Submitted by: V.Ramachandran.
-------------------------------------------------------------------------
WDJ SDK Annotation #141
TYPE: Win32
TOPIC: WM_SETICON
KEYWORD: WM_SETICON AND "See also"
Contrary to what the documentation says, Windows uses the small icon in
the window caption (including the caption of the minimized window).
Windows uses the large icon when you press Alt+Tab to switch to another
application.
----------------------------------------------------------------------
WDJ SDK Annotation #142
TYPE: Win16
TOPIC: JournalRecordProc
KEYWORD: JournalRecordProc
lParam is incorrectly documented -- it actually points to a
EVENTMSG structure.
----------------------------------------------------------------------
WDJ SDK Annotation #143
TYPE: Win32
TOPIC: GetDeviceCaps
KEYWORD: GetDeviceCaps AND "See also"
The documentation fails to mention 2 additional values for the
index parameter:
SCALINGFACTORX - Scaling factor for the x-axis of a printer
SCALINGFACTORY - Scaling factor for the y-axis of a printer
Also, GetDeviceCaps provides the following 6 indices in place of
printer Escapes:
Index for GetDeviceCaps Printer Escape Replaced
--------------------------------------------------------
PHYSICALWIDTH GETPHYSPAGESIZE
PHYSICALHEIGHT GETPHYSPAGESIZE
PHYSICALOFFSETX GETPRINTINGOFFSET
PHYSICALOFFSETY GETPRINTINGOFFSET
SCALINGFACTORX GETSCALINGFACTOR
SCALINGFACTORY GETSCALINGFACTOR
Reference: MSDN Knowledge Base PSS Q125692
Submitted by Sudhir Menon.
----------------------------------------------------------------------
WDJ SDK Annotation #144
TYPE: Win32
TOPIC: MessageBoxIndirect
KEYWORD: MessageBoxIndirect AND "See also"
The documentation incorrectly mentions that this function returns a
BOOL value, and gives no description of it. In fact, the return value
is an int, and it has the same meaning as the return value for MessageBox.
Submitted by Phil Rodgers.
----------------------------------------------------------------------
WDJ SDK Annotation #145
TYPE: Win32
TOPIC: LVM_EDITLABEL
KEYWORD: LVM_EDITLABEL AND "See also"
Note that the listview control allows label editing
by creating a child edit control with an ID of IDOK.
That edit control will send notifications to the parent
of the listview control (e.g., your dialog box), so
if you have an "OK" button with the same ID, do not
write code like this:
if(Command == IDOK)
EndDialog(Dialog, TRUE);
since the first time the user edits a label, the dialog
will immediately disappear as though the user pressed
the "OK" button. Instead, use code like this:
if(Command == IDOK && Code == BN_CLICKED)
EndDialog(Dialog, TRUE);
----------------------------------------------------------------------
WDJ SDK Annotation #146
TYPE: Win32
TOPIC: TVN_ENDLABELEDIT
KEYWORD: TVN_ENDLABELEDIT AND "See also"
When editing labels in a TreeView control which is part of a dialog,
this notification is sent only if the user ends label editing using
the mouse (by clicking outside the edit control). Using the Enter and
Return keys do not work because the edit control does not handle the
WM_GETDLGCODE correctly, and therefore IsDialogMessage processes these
keys.
In order to make the TreeView control accept the changes when the user
presses Enter, and reject the changes on Escape, do the following:
1. In the TVN_BEGINLABELEDIT notification, get the edit contol handle
using TVM_GETEDITCONTROL. Subclass the edit control.
2. In the subclassed procedure, handle the WM_GETDLGCODE message and
return WM_WANTALLKEYS.
3. Handle the WM_CHAR message. When wParam is VK_ESCAPE, send a
TVM_ENDLABELEDITNOW message to the edit control with fCancel = TRUE.
When wParam is VK_RETURN, send TVM_ENDLABELEDITNOW with
fCancel = FALSE. All other WM_CHAR messages should be passed to the
default edit control procedure.
4. In the TVN_ENDLABELEDIT notification, remove the subclassing.
Reference: MSDN article PSS Q130691
----------------------------------------------------------------------
WDJ SDK Annotation #147
TYPE: Win16
TOPIC: GetWindowTextLength
KEYWORD: GetWindowTextLength
In Windows 3.1, calling GetWindowTextLength on a drop list
combo box (CBS_DROPDOWNLIST) incorrectly returns -1.
However in Win32 (for both 16 and 32 bit applications),
GetWindowTextLength returns the length of the string in the static
portion of the combo box.
Submitted by Sinisa Djurekovic.
----------------------------------------------------------------------
WDJ SDK Annotation #147
TYPE: Win32
TOPIC: GetWindowTextLength
KEYWORD: GetWindowTextLength AND "See also"
In Windows 3.1, calling GetWindowTextLength on a drop list
combo box (CBS_DROPDOWNLIST) incorrectly returns -1.
However in Win32 (for both 16 and 32 bit applications),
GetWindowTextLength returns the length of the string in the static
portion of the combo box.
Submitted by Sinisa Djurekovic.
----------------------------------------------------------------------
WDJ MFC Annotation #147
TYPE: MFC 1.x, 2.x
TOPIC: CWnd::GetWindowText
KEYWORD: CWnd::GetWindowText AND CString AND Parameters
If you call GetWindowText (CString&) on a CWnd object which specifies a
Combo box with the CBS_DROPDOWNLIST style, you will get an assertion
in strcore.cpp.
This is because GetWindowText internally calls GetWindowTextLength.
Calling GetWindowTextLength on a drop list combo box (CBS_DROPDOWNLIST)
incorrectly returns -1, and MFC asserts because -1 is an invalid length
for a CString object.
Submitted by Sinisa Djurekovic.
----------------------------------------------------------------------
WDJ SDK Annotation #148
TYPE: Win32
TOPIC: FindFirstFile
KEYWORD: FindFirstFile AND "See also"
In Windows 95, the FindFirstFile() function interprets a wildcard (?) as
"any character" instead of "zero or one character," as you would expect.
For example, if the files, TEMP.TXT and TEMPTEMP.TXT, are in the same
directory, using FindFirstFile ("TEM?????.???", &findData) finds the
TEMPTEMP.TXT file, but not the TEMP.TXT file:
This function works correctly under Windows NT.
Reference: MSDN PSS ID No. Q130860
----------------------------------------------------------------------
WDJ SDK Annotation #149
TYPE: Win32
TOPIC: CreateDirectoryEx
KEYWORD: CreateDirectoryEx AND "See also"
When you specify a template directory string with two back slashes (\\)
at the end of the string, CreateDirectoryEx returns FALSE indicating
error, even though the API successfully created the new directory.
GetLastError returns ERROR_INVALID_PARAMETER (87L).
Under Windows 95, passing "c:\\" as the template directory (first
parameter) to CreateDirectoryEx will return FALSE, even if it
successfully created the new directory.
The function works correctly under Windows NT.
Reference: MSDN PSS ID No. Q140455
----------------------------------------------------------------------
WDJ MFC Annotation #150
TYPE: MFC
TOPIC: CStatusBar::SetPaneText
KEYWORD: CStatusBar::SetPaneText AND "See also"
Just calling CStatusBar::SetPaneText will not display the text in the
status bar pane. You need to add a UI update handler for the pane for the
text to appear correctly.
In order to set the text for pane index 4, and id ID_PANE_FOUR do:
SetPaneText (4, "Some text", TRUE);
and a UI handler in the message map as follows:
ON_UPDATE_COMMAND_UI (ID_PANE_FOUR, OnUpdatePane)
and in the appropriate .cpp file add:
void CMyClass::OnUpdatePane (CCmdUI *pCmdUI)
{
pCmdUI->Enable ();
}
Reference: MSDN PSS No. Q109039
----------------------------------------------------------------------
WDJ MFC Annotation #151
TYPE: MFC 2.x
TOPIC: CRecordSet::Open
KEYWORD: CRecordSet::Open
The documentation says that, for the param dwOptions, an enum
"CRecordset::defaultOptions" can be specified, which will make the
recordset updatable. However, this enum is not defined. Use
"CRecordset::none" instead.
Submitted by Nagendra R.
----------------------------------------------------------------------
WDJ SDK Annotation #152
TYPE: Win16
TOPIC: EnumFontFamProc
KEYWORD: EnumFontFamProc
The SDK documentation incorrectly mentions that the first parameter
lpnlf points to a NEWLOGFONT structure, which is not defined at all.
lpnlf actually points to a ENUMLOGFONT structure.
Reference: MSDN KB Q87975
Submitted by V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #153
TYPE: Win32
TOPIC: WM_CANCELMODE
KEYWORD: WM_CANCELMODE AND "See also"
The WM_CANCELMODE gets sent to the active window before another dialog or
message box is displayed. It is not sent to the focus window as the
documentation claims.
Therefore if a OK Button in Dialog 1 displays Dialog 2, Dialog 1 gets a
WM_CANCELMODE message and not the OK button, which should have been the
case as per the documentation.
Submitted by V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #154
TYPE: Win32
TOPIC: CreateWindow
KEYWORD: CreateWindow AND "See also"
The documentation does not mention that static controls created with the
SS_SIMPLE style do not gray their text when they are disabled unlike
static controls without the SS_SIMPLE style.
Submitted by Nagendra R.
----------------------------------------------------------------------
WDJ MFC Annotation #155
TYPE: MFC 4.x
TOPIC: CFileDialog::GetNextPathName
KEYWORD: CFileDialog::GetNextPathName
If you select multiple files in a root drive, GetNextPathName returns
strings with two back slashes '\' after the drive letter. For example, if
you select the autoexec.bat and config.sys files from C:\ using a multiple
selection file open dialog, GetNextPathName will return the strings:
"c:\\autoexec.bat" and "c:\\config.sys". This problem does not appear when
you select only one file.
A workaround would be to check the strings returned by GetNextPathName for
double back slashes, and remove them yourself.
CString sFile = dlg.GetNextPathName (pos);
#if _MFC_VER >= 0x0400
if ((sFile [1] == ':') && (sFile [2] == '\\') && (sFile [3] == '\\')) {
sFile = sFile.Left (3) + sFile.Right (sFile.GetLength () - 4);
}
#endif // end of MFC 4.x hack!
Submitted by David Lowndes.
----------------------------------------------------------------------
WDJ MFC Annotation #156
TYPE: MFC 4.x
TOPIC: CToolTipCtrl::GetToolInfo
KEYWORD: CToolTipCtrl::GetToolInfo
The documentation incorrectly states that the first parameter should be
of type LPTOOLINFO. The function actually accepts a CToolInfo& (reference
to a undocumented CToolInfo class). If the call succeeds, the szText
parameter of the CToolInfo variable contains the tooltip text.
Submitted by Paul Stemper.
----------------------------------------------------------------------
WDJ MFC Annotation #157
TYPE: MFC 4.x
TOPIC: CToolTipCtrl::AddTool
KEYWORD: CToolTipCtrl::AddTool
The documentation fails to mention that you cannot set a tooltip to a
static control using the AddTool function.
Submitted by Sudhir Menon.
----------------------------------------------------------------------
WDJ MFC Annotation #158
TYPE: MFC 4.x
TOPIC: CTreeCtrl::GetNextVisibleItem
KEYWORD: CTreeCtrl::GetNextVisibleItem
GetNextVisibleItem and GetPrevVisibleItem return the next
or previous item, not the next or previous visible item.
Submitted by Mark Gorokhov.
----------------------------------------------------------------------
WDJ MFC Annotation #158
TYPE: MFC 4.x
TOPIC: CTreeCtrl::GetPrevVisibleItem
KEYWORD: CTreeCtrl::GetPrevVisibleItem
GetNextVisibleItem and GetPrevVisibleItem return the next
or previous item, not the next or previous visible item.
Submitted by Mark Gorokhov.
----------------------------------------------------------------------
WDJ MFC Annotation #159
TYPE: MFC 4.x
TOPIC: CFontDialog::GetCurrentFont
KEYWORD: CFontDialog::GetCurrentFont
Though the documentation mentions that you can call this function after
calling DoModal, the function incorrectly ASSERTS that its window handle
is not NULL.
Instead, use the public CFontDialog member variable m_lf.
Submitted by Tim Lesher.
----------------------------------------------------------------------
WDJ SDK Annotation #160
TYPE: Win32
TOPIC: WM_MOVE
KEYWORD: WM_MOVE AND "See also"
The SDK documentation tells you to use the following two lines to calculate
the x, and y positions of the window after it has been moved.
xPos = (int) LOWORD(lParam); // horizontal position
yPos = (int) HIWORD(lParam); // vertical position
Though this worked fine in 16-bit Windows, it will fail for negative
coordinates in 32-bit Windows. Instead use the following two lines to
calculate the coordinates:
xPos = (int) (short)LOWORD(lParam); // horizontal position
yPos = (int)(short) HIWORD(lParam); // vertical position
Submitted by Steven M. Kinney.
----------------------------------------------------------------------
WDJ MFC Annotation #161
TYPE: MFC 4.x
TOPIC: CWnd::OnMove
KEYWORD: CWnd::OnMove AND Parameters NOT LPRECT
MFC supplies LOWORD (lParam) and HIWORD (lParam) of the WM_MOVE message
for the x, and y parameters of this function, respectively. Since x and y
are defined as integers, you will get very large numbers for negative
coordinates.
Whenever you want to handle the WM_MOVE message, do the following:
1. Define a message handler: ON_MESSAGE (WM_MOVE, OnMyMove) in the message
map.
2. Write the OnMyMove function as follows:
LRESULT ClassName::OnMyMove (WPARAM, LPARAM lParam)
{
x = (int) (short)LOWORD(lParam); // horizontal position
y = (int)(short) HIWORD(lParam); // vertical position
// Do your processing here ...
return Default ();
}
Submitted by Steven M. Kinney.
----------------------------------------------------------------------
WDJ MFC Annotation #162
TYPE: MFC 2.x
TOPIC: CRecordset::Delete
KEYWORD: CRecordset::Delete AND Remarks NOT Symptoms
This function is incorrectly documented as returning BOOL. It actually
returns void.
This documentation error has been corrected in MFC 4.x
Submitted by Tushar Bhatia.
----------------------------------------------------------------------
WDJ SDK Annotation #163
TYPE: Win32
TOPIC: EM_GETLINE
KEYWORD: EM_GETLINE AND "See also"
When using this message under Win32s (1.30a and above) with
the RichEdit control, the parameters the message takes are:
wParam = 0;
lParam = &em32s;
Where em32s is a structure defined as:
struct EM32S {
DWORD wParam;
DWORD lParam;
};
The documented wParam and lParam values are stored in the
EM32S structure.
Submitted by Larry Widing.
----------------------------------------------------------------------
WDJ SDK Annotation #163
TYPE: Win32
TOPIC: EM_LINEINDEX
KEYWORD: EM_LINEINDEX AND "See also"
When using this message under Win32s (1.30a and above) with
the RichEdit control, the parameters the message takes are:
wParam = 0;
lParam = &em32s;
Where em32s is a structure defined as:
struct EM32S {
DWORD wParam;
DWORD lParam;
};
The documented wParam and lParam values are stored in the
EM32S structure.
Submitted by Larry Widing.
----------------------------------------------------------------------
WDJ SDK Annotation #163
TYPE: Win32
TOPIC: EM_LINELENGTH
KEYWORD: EM_LINELENGTH AND "See also"
When using this message under Win32s (1.30a and above) with
the RichEdit control, the parameters the message takes are:
wParam = 0;
lParam = &em32s;
Where em32s is a structure defined as:
struct EM32S {
DWORD wParam;
DWORD lParam;
};
The documented wParam and lParam values are stored in the
EM32S structure.
Submitted by Larry Widing.
----------------------------------------------------------------------
WDJ SDK Annotation #163
TYPE: Win32
TOPIC: EM_LINESCROLL
KEYWORD: EM_LINESCROLL AND "See also"
When using this message under Win32s (1.30a and above) with the RichEdit
control, the parameters the message takes are:
wParam = 0;
lParam = &em32s;
Where em32s is a structure defined as:
struct EM32S {
DWORD wParam;
DWORD lParam;
};
The documented wParam and lParam values are stored in the EM32S structure.
Submitted by Larry Widing.
----------------------------------------------------------------------
WDJ SDK Annotation #164
TYPE: Win32
TOPIC: EDITSTREAM
KEYWORD: EDITSTREAM AND "See also"
The return value from this function is incorrectly
documented. The return value from the EditStreamCallback is
interpreted as an SCODE - you should return 0 to indicate
success or an error code otherwise (both while reading and
writing).
Reference: MSDN KB article Q136810
Submitted by Donald Munro.
----------------------------------------------------------------------
WDJ SDK Annotation #165
TYPE: Win16
TOPIC: GetNextDlgGroupItem
KEYWORD: GetNextDlgGroupItem
The Win16 SDK fails to mention that this function ignores
controls that are part of the group but are disabled. The
documentation has been corrected in Win32.
If you use MFC, check out Annotation #166 (DDX_Radio) for
this bug's repercussions.
----------------------------------------------------------------------
WDJ MFC Annotation #166
TYPE: MFC
TOPIC: DDX_Radio
KEYWORD: DDX_Radio
DDX_Radio internally uses GetNextDlgGroupItem (see SDK
annotation #165) and therefore ignores disabled
radio-buttons. This could causes 2 radio buttons in the
same group to be selected, if a disabled radio-button is
selected. Generally, you are better off not using this
function if you are going to enable/disable radio-buttons.
Use the Windows SDK functions instead. This applies to MFC
1.x and 2.x.
Reference: MSDN KB Q114980
----------------------------------------------------------------------
WDJ SDK Annotation #167
TYPE: Win32
TOPIC: CreatePen
KEYWORD: CreatePen AND "See also"
If you specify a width greater than 1 for one of the the
following styles - PS_DASH, PS_DOT, PS_DASHDOT,
PS_DASHDOTDOT, CreatePen returns a pen with the specified
width but with the PS_SOLID style.
Submitted by Muthuvale Shanmugam.
----------------------------------------------------------------------
WDJ SDK Annotation #168
TYPE: Win32
TOPIC: WindowFromPoint
KEYWORD: WindowFromPoint AND "See also"
If given a point over a static control, WindowFromPoint()
returns the handle of the window "under" the static text control.
Submitted by Muthuvale Shanmugam.
----------------------------------------------------------------------
WDJ SDK Annotation #169
TYPE: Win32
TOPIC: TranslateMessage
KEYWORD: TranslateMessage AND "See also"
Though the documentation mentions that it returns TRUE only
if it translates message, it actually returns TRUE for all
WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN and WM_SYSKEYUP
messages. This behaviour is consistent with Windows 3.1
Reference: MSDN KB Q137231
----------------------------------------------------------------------
WDJ SDK Annotation #170
TYPE: Win32
TOPIC: LoadLibrary
KEYWORD: LoadLibrary AND "See also"
When writing code for a Win32 DLL, you may be tempted to
use declare thread-local variables using Windows-specific
keywords like this:
__declspec(thread) int ThisThreadStatus;
If you do, however, then the resulting DLL can only be
loaded implicitly (by linking with an import library).
If any program tries to use LoadLibrary() or LoadLibraryEx()
to load such a DLL, the call will fail and GetLastError()
will report a code of 1114L (DLL initialization failed),
even though your DLL's entry point never gets called.
The only work around is to simply not use __declspec(thread)
in your DLL. Either use the TlsXxxx() functions to allocate
thread-local storage, or use your own algorithm for associating
data with thread handles.
----------------------------------------------------------------------
WDJ SDK Annotation #171
TYPE: Win32
TOPIC: GetLastError
KEYWORD: GetLastError AND "See also" NOT MAPIERROR
Some versions of the documentation for GetLastError() state
that a listing of the error codes is found in WINNT.H. The
list of error codes is actually found in the file
WINERROR.H.
Submitted by Katy Mulvey.
----------------------------------------------------------------------
WDJ SDK Annotation #172
TYPE: Win32
TOPIC: WaitForMultipleObjects
KEYWORD: WaitForMultipleObjects AND "See also"
The Windows 95 implementation of this function
has a bug (see the reference for a complete
explanation). If the same thread claims a mutex
more than once, then a second thread calls
WaitForMultipleObjects() to wait on that mutex and at
least one other object, WaitForMultipleObjects() will
incorrectly consider the mutex free when the other
objects being waited on become signaled.
Reference: p. 44, December 1996 Windows Developer's Journal
----------------------------------------------------------------------
WDJ SDK Annotation #173
TYPE: Win32
TOPIC: TBBUTTON
KEYWORD: TBBUTTON AND "See also"
The documentation incorrectly claims that for
separators (fsStyle equal to TBSTYLE_SEP), the
idCommand field must be zero. In fact, you can
assign toolbar separators a non-zero ID. In fact,
it is important to assign unique IDs to separators
if they have non-default widths so the customization
features will work properly. Also, it's a common
technique to use a "fat" separator as a placeholder
for a control (such as a drop-down listbox) that you
want to appear on the toolbox. You will need to
assign such separators a non-zero ID so that you
can locate the correct position for the control.
Reference: p. 45, November 1996 Windows Developer's Journal
----------------------------------------------------------------------
WDJ SDK Annotation #174
TYPE: Win32
TOPIC: WM_GETDLGCODE
KEYWORD: WM_GETDLGCODE AND "See also"
If a 32-bit control returns DLGC_HASSETSEL, Windows 95 will not send a
EM_SETSEL message when the control gets the focus. Instead, Windows 95
sends the control a message with the same value as the 16-bit EM_SETSEL
(0x401) with 16-bit style parameters. Under Windows NT, your control
will get the normal 32-bit EM_SETSEL message.
Note: Under Win32, the EM_ messages start at 0xB0 and not at WM_USER
(0x400) as they did in Win16.
Submitted by Robert Mashlan.
------------------------------------------------------------------------
WDJ SDK Annotation #175
TYPE: Win32
TOPIC: GetRegionData
KEYWORD: GetRegionData AND "See also"
The documentation for the return value is incorrect. If the
function succeeds and dwCount specifies an adequate number
of bytes, the return value is always dwCount. If the
function fails or if dwCount specifies less than adequate
number of bytes, the return value is 0.
Submitted by Peter C. Jahans.
----------------------------------------------------------------------
WDJ MFC Annotation #175
TYPE: MFC
TOPIC: CRgn::GetRegionData
KEYWORD: CRgn::GetRegionData
The documentation for the return value is incorrect. If the
function succeeds and dwCount specifies an adequate number
of bytes, the return value is always dwCount. If the
function fails or if dwCount specifies less than adequate
number of bytes, the return value is 0 (ERROR).
Submitted by Peter C. Jahans.
----------------------------------------------------------------------
WDJ SDK Annotation #176
TYPE: Win32
TOPIC: DrawFocusRect
KEYWORD: DrawFocusRect AND "See also"
DrawFocusRect() works only in MM_TEXT mode. In other
modes, this function does not draw the focus rectangle
correctly, but it does NOT return error values!
Submitted by Jon-David Wiesman.
----------------------------------------------------------------------
WDJ MFC Annotation #176
TYPE: MFC
TOPIC: CDC::DrawFocusRect
KEYWORD: CDC::DrawFocusRect
CDC::DrawFocusRect() works only in MM_TEXT mode. In other
modes, this function does not draw the focus rectangle
correctly, but it does NOT return error values!
Submitted by Jon-David Wiesman.
----------------------------------------------------------------------
WDJ SDK Annotation #177
TYPE: Win32
TOPIC: FSCTL_DISMOUNT_VOLUME
KEYWORD: FSCTL_DISMOUNT_VOLUME AND "See also"
The SDK documentation for this function mentions "If the
specified volume is locked, the operation fails." This is
incorrect. It should actually read "If the specified volume
is locked by another process, the operation fails." You must
do an FSCTL_LOCK_VOLUME before you can do an
FSCTL_DISMOUNT_VOLUME.
Also, in the sequence of events for reformatting FAT to NTFS
as described in the same article, steps 4 and 5 must be
switched - you need to dismount the volume before you unlock
the volume.
Submitted by Jeffrey S. Goldner.
----------------------------------------------------------------------
WDJ SDK Annotation #178
TYPE: Win32
TOPIC: CreateProcess
KEYWORD: CreateProcess AND "See also"
If you call CreateProcess() with a dwCreationFlags value
which includes DEBUG_PROCESS, the call will fail under Win95
when the debugee is a 16-bit app.
Submitted by Marc Cousineau.
----------------------------------------------------------------------
WDJ SDK Annotation #179
TYPE: Win32
TOPIC: WM_ACTIVATE
KEYWORD: WM_ACTIVATE AND "See also"
The documentation states that the message is sent first to
the top-level window being deactivated and then to the
window being activated. This is incorrect in Win32. In
Win32, activation is asynchronous - the activating
application becomes active immediately and the messages to
the deactivating application occur later.
Reference: MSDN KB Article Q135785
Submitted by V.Ramachandran.
----------------------------------------------------------------------
WDJ MFC Annotation #179
TYPE: MFC
TOPIC: CWnd::OnActivate
KEYWORD: CWnd::OnActivate
The documentation states that first OnActivate() is called
for the main window being deactivated, and then for the main
window being activated This is incorrect in Win32. In
Win32, activation is asynchronous - the activating
application becomes immediately and the messages to the
deactivating application occur later.
Reference: MSDN KB Article Q135785
Submitted by V.Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #180
TYPE: Win32
TOPIC: DRAWITEMSTRUCT
KEYWORD: DRAWITEMSTRUCT AND "See also"
Listviews always set the itemAction member to
ODA_DRAWENTIRE. You need to check the itemState member to
check if the focus or selection needs to be updated.
Reference: MSDN KB Article Q131788
Submitted by V.Ramachandran.
----------------------------------------------------------------------
WDJ MFC Annotation #181
TYPE: MFC 4.2
TOPIC: CInternetSession::ServiceTypeFromHandle
KEYWORD: CInternetSession::ServiceTypeFromHandle
The on-line help states
CInternetSession::ServiceTypeFromHandle() returns the type
of service given the internet handle. Although this
function is declared in afxinet.h, it is not defined
anywhere. Using this function will cause your program to
fail at link time.
Submitted by Mario Contestabile.
----------------------------------------------------------------------
WDJ MFC Annotation #182
TYPE: MFC 4.2
TOPIC: CHttpFile::QueryInfo
KEYWORD: CHttpFile::QueryInfo
The documentation for CHttpFile::QueryInfo() erroneously states some of
the possible values for lpdwIndex and dwIndex:
HTTP_QUERY_LANGUAGE is actually HTTP_QUERY_CONTENT_LANGUAGE
HTTP_QUERY_ALLOWED_METHODS is actually HTTP_QUERY_ALLOW
HTTP_QUERY_PUBLIC_METHODS is actually HTTP_QUERY_PUBLIC
(All #defines in wininet.h)
Submitted by Mario Contestabile.
----------------------------------------------------------------------
WDJ MFC Annotation #183
TYPE: MFC 4.x
TOPIC: COleDateTime::GetYear
KEYWORD: COleDateTime::GetYear
If the status of this COleDateTime object is not valid, the
return value is AFX_OLE_DATETIME_ERROR and not
AFX_DATETIME_ERROR as documented. This affects the following
member functions: GetYear(), GetMonth(), GetDay(), GetHour(),
GetMinute(), GetSecond(), GetDayOfWeek(), and GetDayOfYear().
Submitted by Mario Contestabile.
----------------------------------------------------------------------
WDJ SDK Annotation #184
TYPE: Win32
TOPIC: ScrollWindowEx
KEYWORD: ScrollWindowEx AND "See also"
If the prcClip parameter is NULL, no clipping is performed on the
scroll rectangle.
Submitted by V. Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #185
TYPE: Win32
TOPIC: WM_CONTEXTMENU
KEYWORD: WM_CONTEXTMENU AND "See also"
If the user uses the keyboard shortcut (Shift-F10 or the special
key on a Microsoft keyboard) to activate the context menu, the
xPos and yPos parameters are -1, -1.
Submitted by Katy Mulvey.
----------------------------------------------------------------------
WDJ SDK Annotation #186
TYPE: Win32
TOPIC: GetLastError
KEYWORD: GetLastError AND "return values" AND parameters NOT S_OK
The Win32 Programmer's Reference documentation for
GetLastError() incorrectly states that a listing of the
error codes is found in WINNT.H. It is actually found in
the file WINERROR.H
Note: This error has been corrected in the Jan 97 MSDN.
Submitted by Katy Mulvey.
----------------------------------------------------------------------
WDJ SDK Annotation #187
TYPE: Win32
TOPIC: CreateWindowEx
KEYWORD: CreateWindowEx AND "See also"
The documentation does not mention that you can call GetLastError
to get extended error information if the function fails.
Submitted by V. Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #188
TYPE: Win32
TOPIC: WM_SYSCOMMAND
KEYWORD: WM_SYSCOMMAND AND "See also"
If the wParam is SC_KEYMENU, the lParam contains the
character code of the key used in combination with the Alt
key to display the popup menu. For example, pressing Alt+F
to display the File popup will cause a WM_SYSCOMMAND with
wParam equal to SC_KEYMENU and lParam equal to 'f'.
Reference: MSDN Article ID Q92527.
Submitted by V. Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #189
TYPE: Win32
TOPIC: CreateWindow
KEYWORD: CreateWindow AND "See also"
For creating static controls with the SS_ICON style, you
need to specify the icon name in the lpWindowName parameter.
However, if you have an icon resource identified with a
numeric id (instead of a string), you need to specify #xxx
(where xxx is the numeric identifier for the ICON resource)
in the lpWindowName parameter. You should not use the
MAKEINTRESOURCE macro.
Submitted by V. Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #189
TYPE: Win32
TOPIC: CreateWindowEx
KEYWORD: CreateWindowEx AND "See also"
For creating static controls with the SS_ICON style, you
need to specify the icon name in the lpWindowName parameter.
However, if you have an icon resource identified with a
numeric id (instead of a string), you need to specify #xxx
(where xxx is the numeric identifier for the ICON resource)
in the lpWindowName parameter. You should not use the
MAKEINTRESOURCE macro.
Submitted by V. Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #190
TYPE: Win32
TOPIC: WM_GETTEXT
KEYWORD: WM_GETTEXT AND "See also"
In Win32, you cannot send the WM_SETTEXT to a static control
with the SS_ICON style to set the icon. Therefore, you
should not use the WM_GETTEXT message to retrieve the icon
handle of static controls with the SS_ICON style. Use the
STM_SETICON and STM_GETICON messages instead.
Submitted by V. Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #191
TYPE: Win32
TOPIC: RegisterHotKey
KEYWORD: RegisterHotKey AND "See also"
If you want to disable task switching under Win32, you can
do so by registering hot keys for Ctrl+Esc and Alt+Tab.
Reference: MSDN Article ID Q125614
Submitted by V. Ramachandran.
----------------------------------------------------------------------
WDJ SDK Annotation #192
TYPE: Win32
TOPIC: CreateFile
KEYWORD: CreateFile AND "See also"
Under Windows NT, when CreateFile is used with the
dwCreationDistribution parameter equal to CREATE_ALWAYS,
the call fails if the file exists and is hidden.
GetLastError() returns ERROR_ACCESS_DENIED. However, the
call succeeds under Windows 95 creating a new file that is
not hidden.
Submitted by Abdul Nizar.
----------------------------------------------------------------------
WDJ MFC Annotation #192
TYPE: MFC 4.x
TOPIC: CFile::Open
KEYWORD: CFile::Open
Under Windows NT, if the nOpenFlags parameter is ORed with
CFile::modeCreate and not ORed with CFile::modeNoTruncate,
CFile::Open fails if the file exists and is hidden. However,
the call succeeds under Windows 95 creating a new file that
is not hidden.
Submitted by Abdul Nizar.
----------------------------------------------------------------------
WDJ MFC Annotation #193
TYPE: MFC
TOPIC: CListCtrl::SetColumnWidth
KEYWORD: CListCtrl::SetColumnWidth
The cx parameter is the new width of the column in listview
coordinates, or one of the following
LVSCW_AUTOSIZE Automatically sizes the column.
LVSCW_AUTOSIZE_USEHEADER Automatically sizes the column to
fit the header text
Submitted by Ramon de Klein.
----------------------------------------------------------------------
WDJ SDK Annotation #194
TYPE: Win32
TOPIC: PeekMessage
KEYWORD: PeekMessage AND "See also"
PeekMessage will always retrieve WM_QUIT messages,
irrespective of the setting of uMsgFilterMin and
uMsgFilterMax.
Submitted by Graham King.
----------------------------------------------------------
WDJ MFC Annotation #195
TYPE: MFC 4.x
TOPIC: CWinApp::OnIdle
KEYWORD: CWinApp::OnIdle
If you do not want OnIdle to be called whenever a
message is retrieved from the message queue, you can
override the IsIdleMessage. If an application has set
a very short timer or if the system is sending the
undocumented WM_SYSTIMER (0x118) message, then OnIdle
will be called repeatedly, and degrade performance.
Submitted by Adrian Pybus.
----------------------------------------------------------
WDJ MFC Annotation #196
TYPE: MFC 4.x
TOPIC: CImageList::Create
KEYWORD: CImageList::Create
The documentation for argument bMask is incorrect. In
fact this value is a UINT bitmask, and accepts
combinations of the following values:
ILC_MASK 0x0001 // ImageList has a mask
ILC_COLORDDB 0x00FE // use device dependent bitmap
ILC_COLOR4 0x0004 // use 4bpp DIBSection
ILC_COLOR8 0x0008 // use 8bpp DIBSection
ILC_COLOR16 0x0010 // use 16bpp DIBSection
ILC_COLOR24 0x0018 // use 24bpp DIBSection
ILC_COLOR32 0x0020 // use 32bpp DIBSection
ILC_PALETTE 0x0800 // use palette with image list
Refer to ImageList_Create for more information about
these flags.
Submitted by Frank Brown.
----------------------------------------------------------
WDJ SDK Annotation #197
TYPE: Win32
TOPIC: NetServerDiskEnum
KEYWORD: NetServerDiskEnum AND "See also"
The Win32 documentation for NetServerDiskEnum is
incorrect on the following four points:
1. The 'level' parameter has to be 0, and not 100 as documented.
2. The function returns the enumerated disks as an array
of 3 character Unicode strings pointed to by the bufptr
parameter.
3. NetServerDiskEnum fails if its "servername" argument
is a Win95 computer.
4. This function is available only on NT (Unicode only).
However, the header file (lmserver.h) declarations
specify LPTSTR for string parameters - they actually
require LPWSTR strings.
You would call this function as follows:
WCHAR (*pDrives)[3] = NULL;
ret = NetServerDiskEnum(
(LPTSTR)servername,
0,
(LPBYTE *)(&pDrives),
0,
&entriesRead,
&totalEntries,
&resumeHandle ) ;
Submitted by Aaron J Margosis.
----------------------------------------------------------
WDJ SDK Annotation #198
TYPE: Win32
TOPIC: StringFromGUID2
KEYWORD: StringFromGUID2 AND "See also"
The string received is enclosed by curly braces like
the following sample and not square braces as indicated
in the documentation.
{c200e360-38c5-11ce-ae62-08002b2b79ef}
Submitted by V.Ramachandran.
----------------------------------------------------------
WDJ SDK Annotation #199
TYPE: Win32
TOPIC: GetUpdateRect
KEYWORD: GetUpdateRect AND "See also"
If the window was created with the CS_OWNDC style,
GetUpdateRect always retrieves the rectangle in
logical coordinates irrespective of the mapping mode.
Submitted by V.Ramachandran.
----------------------------------------------------------
WDJ SDK Annotation #200
TYPE: Win32
TOPIC: BrowseCallbackProc
KEYWORD: BrowseCallbackProc AND "See also"
The documentation errs in the parameters for the
notifications:
BFFM_INITIALIZED: lParam is 0, lpData is the application
defined value specified in the BROWSEINFO structure.
BFFM_SELCHANGED: lParam points to the item identifier list
for the newly selected item, lpData is the application
defined value specified in the BROWSEINFO structure.
For the BFFM_ENABLEOK message, the lParam should be 0
for disabling, and non-zero for enabling the OK button,
and not the wParam as documented.
Submitted by John Bates.
----------------------------------------------------------
WDJ SDK Annotation #201
TYPE: Win32
TOPIC: SHBrowseForFolder
KEYWORD: SHBrowseForFolder AND "See also"
If the BIF_RETURNONLYFSDIRS flag is specified, the
OK button stays enabled for a "\\computer" item, not
just the "\\computer\share" and directory items.
SHGetPathFromIDList() will fail if you pass it the
LPITEMIDLIST returned from SHBrowseForFolder when you
select just a computer name.
Submitted by John Bates.
----------------------------------------------------------
WDJ SDK Annotation #202
TYPE: Win32
TOPIC: MoveWindow
KEYWORD: MoveWindow AND "See also"
If the bRepaint flag is FALSE, no repainting of any
kind occurs. The Remarks section is incorrect in saying
that a WM_PAINT message is placed in the message queue.
Submitted by V.Ramachandran.
----------------------------------------------------------
WDJ SDK Annotation #203
TYPE: Win32
TOPIC: WideCharToMultiByte
KEYWORD: WideCharToMultiByte AND "See also"
If the function succeeds, the return value is equal to
the string length plus the terminating NULL character.
If cchMultiByte specifies a value less than necessary,
the function returns 0, and GetLastError returns
ERROR_INSUFFICIENT_BUFFER. However, cchMultiByte
characters are copied to the buffer pointed to by
lpMultiByteStr.
----------------------------------------------------------